From 8dbea3ac244958fcf1b502dfb999a86e12aec7e3 Mon Sep 17 00:00:00 2001 From: Chong Yeo Date: Tue, 22 May 2018 10:38:35 -0700 Subject: [PATCH 01/50] 1. Add the following Cmdlets for vTPM Support Add-Vtpm Remove-Vtpm Get-VtpmCsr Set-VtpmCert Get-VtpmCert 2. Minor Version Change from 1.1 to 1.2 --- .../VMware.VMEncryption.psd1 | 2 +- .../VMware.VMEncryption.psm1 | 2380 ++++++++++++++++- 2 files changed, 2380 insertions(+), 2 deletions(-) diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 index 95b678f..aa83854 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 @@ -12,7 +12,7 @@ # RootModule = '' # Version number of this module. -ModuleVersion = '1.1' +ModuleVersion = '1.2' # ID used to uniquely identify this module GUID = 'f9592e48-6cd3-494e-891b-ee10ee9f7018' diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 index 7752274..0211669 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 @@ -1,3 +1,2381 @@ +# Script Module : VMware.VMEncryption +# Version : 1.1 + +# Copyright © 2016 VMware, Inc. All Rights Reserved. + +# Permission is hereby granted, free of charge, to any person obtaining a copy of +# this software and associated documentation files (the "Software"), to deal in +# the Software without restriction, including without limitation the rights to +# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +# of the Software, and to permit persons to whom the Software is furnished to do +# so, subject to the following conditions: + +# The above copyright notice and this permission notice shall be included in all +# copies or substantial portions of the Software. + +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +# SOFTWARE. + + +New-VIProperty -Name AESNIStatus -ObjectType VMHost -Value { + Param ($VMHost) + $FeatureCap = $VMHost.ExtensionData.Config.FeatureCapability + foreach ($Feature in $FeatureCap) { + if ($Feature.FeatureName -eq "cpuid.AES") { + ($Feature.Value -eq "1") + } + } +} -BasedOnExtensionProperty 'Config.FeatureCapability' -Force | Out-Null + +New-VIProperty -Name CryptoSafeSupported -ObjectType VMHost -Value { + Param ($VMHost) + $VMHost.ExtensionData.Runtime.CryptoState -ne $null +} -BasedOnExtensionProperty 'Runtime.CryptoState' -Force + +New-VIProperty -Name CryptoSafe -ObjectType VMHost -Value { + Param ($VMHost) + $VMHost.ExtensionData.Runtime.CryptoState -eq "safe" +} -BasedOnExtensionProperty 'Runtime.CryptoState' -Force + +New-VIProperty -Name Encrypted -ObjectType VirtualMachine -Value { + Param ($VM) + $VM.ExtensionData.Config.KeyId -ne $null +} -BasedOnExtensionProperty 'Config.KeyId' -Force | Out-Null + +New-VIProperty -Name EncryptionKeyId -ObjectType VirtualMachine -Value { + Param ($VM) + if ($VM.Encrypted) { + $VM.ExtensionData.Config.KeyId + } +} -BasedOnExtensionProperty 'Config.KeyId' -Force | Out-Null + +New-VIProperty -Name Locked -ObjectType VirtualMachine -Value { + Param ($VM) + if ($vm.ExtensionData.Runtime.CryptoState) { + $vm.ExtensionData.Runtime.CryptoState -eq "locked" + } + else { + ($vm.extensiondata.Runtime.ConnectionState -eq "invalid") -and ($vm.extensiondata.Config.KeyId) + } +} -BasedOnExtensionProperty 'Runtime.CryptoState', 'Runtime.ConnectionState','Config.KeyId' -Force | Out-Null + +New-VIProperty -Name vMotionEncryption -ObjectType VirtualMachine -Value { + Param ($VM) + $VM.ExtensionData.Config.MigrateEncryption +} -BasedOnExtensionProperty 'Config.MigrateEncryption' -Force | Out-Null + +New-VIProperty -Name KMSserver -ObjectType VirtualMachine -Value { + Param ($VM) + if ($VM.Encrypted) { + $VM.EncryptionKeyId.ProviderId.Id + } +} -BasedOnExtensionProperty 'Config.KeyId' -Force | Out-Null + +New-VIProperty -Name Encrypted -ObjectType HardDisk -Value { + Param ($hardDisk) + $hardDisk.ExtensionData.Backing.KeyId -ne $null +} -BasedOnExtensionProperty 'Backing.KeyId' -Force | Out-Null + +New-VIProperty -Name EncryptionKeyId -ObjectType HardDisk -Value { + Param ($Disk) + if ($Disk.Encrypted) { + $Disk.ExtensionData.Backing.KeyId + } +} -BasedOnExtensionProperty 'Backing.KeyId' -Force | Out-Null + +Function Enable-VMHostCryptoSafe { + <# + .SYNOPSIS + This cmdlet enables the VMHost's CryptoSate to safe. + + .DESCRIPTION + This cmdlet enables the VMHost's CryptoSate to safe. + + .PARAMETER VMHost + Specifies the VMHost you want to enable. + + .PARAMETER KMSClusterId + Specifies the KMS cluster ID which you want to use to generate the encrytion key. + + .EXAMPLE + C:\PS>$VMHost = Get-VMHost -name $VMHostName + C:\PS>Enable-VMHostCryptoSafe -VMHost $VMHost + + Enables the specified VMHost's CryptoSate to safe. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost] $VMHost, + + [Parameter(Mandatory=$False)] + [String] $KMSClusterId + ) + + Process { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + + if (!$VMHost.CryptoSafeSupported) { + Write-Error "The VMHost: $VMHost does not support CryptoSafe!`n" + return + } + + if ($VMHost.CryptoSafe) { + Write-Error "The VMHost: $VMHost CryptoSafe already enabled!`n" + return + } + + # Generate key from the specified KMS cluster + try { + $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId + } catch { + Throw "Key generation failed, make sure the KMS Cluster exists!`n" + } + + $VMHostView = Get-View $VMHost + $VMHostView.ConfigureCryptoKey($KeyResult.KeyId) + } +} + +Function Set-VMHostCryptoKey { + <# + .SYNOPSIS + This cmdlet changes the VMHost CryptoKey. + + .DESCRIPTION + This cmdlet changes the VMHost CryptoKey if VMHost is already in Crypto safe state. + + .PARAMETER VMHost + Specifies the VMHost whose CryptoKey you want to update. + + .PARAMETER KMSClusterId + Specifies the KMS cluster ID which you want to use to generate the encryption key. + + .EXAMPLE + C:\PS>$VMHost = Get-VMHost -Name $VMHostName + C:\PS>Set-VMHostCryptoKey -VMHost $VMHost + + Changes the VMHost CryptoKey to a new CryptoKey. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost] $VMHost, + + [Parameter(Mandatory=$False)] + [String] $KMSClusterId + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + Process { + if (!$VMHost.CryptoSafeSupported) { + Write-Error "The VMHost: $VMHost does not support CryptoSafe!`n" + return + } + + if (!$VMHost.CryptoSafe) { + Write-Error "The VMHost: $VMHost has not enabled the CrytoSate to safe!" + return + } + + $VMHostView = Get-View $VMHost + $OldKey = $VMHostView.Runtime.CryptoKeyId + + # Generate key from the specified KMSCluster + try { + $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId + } catch { + Throw "Key generation failed, make sure the KMS Cluster exists!`n" + } + + try { + $VMHostView.ConfigureCryptoKey($KeyResult.KeyId) + Write-Verbose "Change Crypto Key on VMHost: $VMHost succeeded!`n" + } catch { + Write-Error "Change Crypto Key on VMHost: $VMHost failed.$_!`n" + return + } + + # Remove the old host key + Write-Verbose "Removing the old hostKey: $($OldKey.KeyId) on $VMHost...`n" + $VMHostCM = Get-View $VMHostView.ConfigManager.CryptoManager + $VMHostCM.RemoveKeys($OldKey, $true) + } +} + +Function Set-vMotionEncryptionConfig { + <# + .SYNOPSIS + This cmdlet sets the vMotionEncryption property of a VM. + + .DESCRIPTION + Use this function to set the vMotionEncryption settings for a VM. + The 'Encryption' parameter is set up with Tab-Complete for the available + options. + + .PARAMETER VM + Specifies the VM you want to set the vMotionEncryption property. + + .PARAMETER Encryption + Specifies the value you want to set to the vMotionEncryption property. + The Encryption options are: disabled, opportunistic, and required. + + .EXAMPLE + PS C:\> Get-VM | Set-vMotionEncryptionConfig -Encryption opportunistic + + Sets the vMotionEncryption of all the VMs + + .NOTES + Author : Brian Graf, Carrie Yang. + Author email : grafb@vmware.com, yangm@vmware.com + #> + + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM, + + [Parameter(Mandatory=$True)] + [ValidateSet("disabled", "opportunistic", "required")] + [String]$Encryption + ) + + process{ + if ($VM.vMotionEncryption -eq $Encryption) { + Write-Warning "The encrypted vMotion state is already $Encrypted, no need to change it." + return + } + + if ($VM.Encrypted) { + Write-Error "Cannot change encrypted vMotion state for an encrypted VM." + return + } + + $VMView = $VM | get-view + $Config = New-Object VMware.Vim.VirtualMachineConfigSpec + $Config.MigrateEncryption = New-Object VMware.Vim.VirtualMachineConfigSpecEncryptedVMotionModes + $Config.MigrateEncryption = $Encryption + + $VMView.ReconfigVM($config) + + $VM.ExtensionData.UpdateViewData() + $VM.vMotionEncryption + } +} + +Function Enable-VMEncryption { + <# + .SYNOPSIS + This cmdlet encrypts the specified VM. + + .DESCRIPTION + This cmdlet encrypts the specified VM. + + .PARAMETER SkipHardDisks + If specified, skips the encryption of the hard disks of the specified VM. + + .PARAMETER VM + Specifies the VM you want to encrypt. + + .PARAMETER Policy + Specifies the encryption policy you want to use. + + .PARAMETER KMSClusterId + Specifies the KMS clusterId you want to use to generate new key for encryption. + + .EXAMPLE + C:\PS>Get-VM -Name win2012|Enable-VMEncryption + + Encrypts the whole VM with default encryption policy. + + .EXAMPLE + C:\PS>$SP = Get-SpbmStoragePolicy -name "EncryptionPol" + C:\PS>Get-VM -Name win2012 |Enable-VMEncryption -Policy $SP -SkipHardDisks + + Encrypts the VM Home with the encryption policy 'EncryptionPol' and skips hard disks encryption. + + .NOTES + This cmdlet assumes there already is KMS defined in vCenter Server. + If VM Home is already encrypted, the cmdlet quits. + If VM Home is not encrypted, encrypt VM Home if SkipHardDisks specified. Otherwise encrypt the VM Home and VM-attached disks. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)] + [VMware.VimAutomation.Storage.Types.V1.Spbm.SpbmStoragePolicy] $Policy, + + [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)] + [String] $KMSClusterId, + + [Parameter(Mandatory=$False)] + [switch]$SkipHardDisks=$False + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + Process { + # VM Home is already encrypted + if ($VM.Encrypted) { + $ErrMsg = "VM $VM is already encrypted, please use: "+ + "Enable-VMDiskEncryption if you want to "+ + "encrypt disks which not encrypted yet!`n" + Write-Error $ErrMsg + return + } + + Write-Verbose "Checking if the VMHost supports CryptoSafe...`n" + $VMhost = $VM|Get-VMHost + if (!$VMHost.CryptoSafeSupported) { + Write-Error "The VMHost: $VMHost does not support CryptoSafe.`n" + return + } + + Write-Verbose "Checking if $VM has no snapshots...`n" + if ($VM|Get-Snapshot) { + Write-Error "$VM has snapshots, please remove all snapshots and try again!`n" + return + } + + Write-Verbose "Checking if $VM powered off...`n" + if ($VM.PowerState -ne "PoweredOff") { + $ErrMsg = "The VM can only be encrypted when powered off, "+ + "but the current power state of $VM is $($VM.PowerState)!`n" + Write-Error $ErrMsg + return + } + + $PolicyToBeUsed = $null + $BuiltInEncPolicy = Get-SpbmStoragePolicy -Name "VM Encryption Policy" + + if ($Policy) { + # Known issue: If the provided policy is created/cloned from + # the default "VM Encryption Policy", + # Or When creating the policy you didn't select 'Custom', + # there will be null-valued Exception. + Write-Verbose "Checking if the provided policy: $Policy is an encryption policy`n" + if (($Policy.Name -ne "VM Encryption Policy") -and !$Policy.CommonRule.Capability.Category.Contains("ENCRYPTION")) { + Write-Error "The policy $Policy is not an encryption policy, exit!" + return + } + $PolicyToBeUsed = $Policy + } else { + Write-Verbose "No storage policy specified, try to use the built-in policy.`n" + if ($BuiltInEncPolicy) { + $PolicyToBeUsed = $BuiltInEncPolicy + } else { + Throw "The built-in policy does not exist, please use: New-SpbmStoragePolicy to create one first!`n" + } + } + + # Encrypt the VM disks if SkipHardDisk not specified + if (!$SkipHardDisks) { + $Disks = $VM|Get-HardDisk + } + + $VMView = Get-View $VM + $ProfileSpec = New-Object VMware.Vim.VirtualMachineDefinedProfileSpec + $ProfileSpec.ProfileId = $PolicyToBeUsed.Id + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.VmProfile = $ProfileSpec + + if ($KMSClusterId) { + # Generate a new key from KMS + try { + $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId + } catch { + Throw "Key generation failed, make sure the specified KMS Cluster exists!`n" + } + + $CryptoKeyId = $KeyResult.KeyId + $CryptoSpec = New-Object VMware.Vim.CryptoSpecEncrypt + $CryptoSpec.CryptoKeyId = $CryptoKeyId + $VMCfgSpec.Crypto = $CryptoSpec + } + + $DeviceChanges = @() + foreach ($Disk in $Disks) { + Write-Verbose "Attaching policy: $PolicyToBeUsed to $Disk`n" + $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $BackingSpec = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec + $DeviceChange.operation = "edit" + $DeviceChange.device = $Disk.extensiondata + $DeviceChange.Profile = $ProfileSpec + $BackingSpec.Crypto = $CryptoSpec + $DeviceChange.Backing = $BackingSpec + $DeviceChanges += $deviceChange + } + + if ($Devicechanges) { + $VMCfgSpec.deviceChange = $Devicechanges + } + + return $VMView.ReconfigVM_Task($VMCfgSpec) + } +} + +Function Enable-VMDiskEncryption { + <# + .SYNOPSIS + This cmdlet encrypts the specified hard disks. + + .DESCRIPTION + This cmdlet encrypts the specified hard disks. + + .PARAMETER VM + Specifies the VM whose hard disks you want to encrypt. + + .PARAMETER Policy + Specifies the encryption policy you want to use. + + .PARAMETER HardDisk + Specifies the hard disks you want to encrypt. + + .PARAMETER KMSClusterId + Specifies the KMS clusterId you want to use to generate new key for encryption. + + .EXAMPLE + C:\PS>$VM = Get-VM -Name win2012 + C:\PS>$VMDisks= $VM|Get-Harddisk|Select -last 2 + C:\PS>Enable-VMDiskEncryption -VM $VM -$HardDisk $VMDisks + + Encrypts the VM disks with the default encryption policy and use the VM encryption key. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.HardDisk[]] $HardDisk, + + [Parameter(Mandatory=$False)] + [VMware.VimAutomation.Storage.Types.V1.Spbm.SpbmStoragePolicy] $Policy, + + [Parameter(Mandatory=$False)] + [String] $KMSClusterId + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + Process { + Write-Verbose "Checking if $VM is encrypted..." + if (!$VM.Encrypted) { + Write-Error "$VM is not encrypted, please use:Enable-VMEncryption to encrypt the VM.`n" + return + } + + # Validate the hard disks + Write-Verbose "Checking the hard disks...`n" + ConfirmHardDiskIsValid -VM $VM -HardDisk $HardDisk + + Write-Verbose "Checking if $VM has no snapshots..." + if ($VM|Get-Snapshot) { + Write-Error "$VM has snapshots, please remove all snapshots!`n" + return + } + + Write-Verbose "Checking if $VM is powered off..." + if ($VM.powerstate -ne "PoweredOff") { + $ErrMsg = "The VM can only be ecrypted when powered off, "+ + "but the current power state of $VM is $($VM.PowerState)!`n" + Write-Error $ErrMsg + return + } + + $PolicyToBeUsed = $null + + if ($Policy) { + # Known issue: If the provided policy is created/cloned from + # the default "VM Encryption Policy", + # Or When creating the policy you didn't select 'Custom', + # there will be null-valued Exception. + Write-Verbose "Checking if the provided policy: $Policy is an encryption policy`n" + if (($Policy.Name -ne "VM Encryption Policy") -and !$Policy.CommonRule.Capability.Category.Contains("ENCRYPTION")) { + Throw "The policy $Policy is not an encryption policy, exit!" + } + $PolicyToBeUsed = $Policy + } else { + Write-Verbose "No storage policy specified, try to use the VM Home policy.`n" + $PolicyToBeUsed = (Get-SpbmEntityConfiguration -VM $VM).StoragePolicy + if (!$PolicyToBeUsed) { + Write-Warning "The VM Home policy is not available, try to use the built-in policy.`n" + $BuiltInEncPolicy = Get-SpbmStoragePolicy -Name "VM Encryption Policy" + if ($BuiltInEncPolicy) { + $PolicyToBeUsed = $BuiltInEncPolicy + } else { + Throw "The built-in policy does not exist, please use: New-SpbmStoragePolicy to create one first!`n" + } + } + } + + # Specify the key used to encrypt disk + if ($KMSClusterId) { + # Generate a new key from KMS + try { + $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId + } catch { + Throw "Key generation failed, make sure the KMS Cluster exists!`n" + } + + $CryptoKeyId = $KeyResult.KeyId + $CryptoSpec = New-Object VMware.Vim.CryptoSpecEncrypt + $CryptoSpec.CryptoKeyId = $CryptoKeyId + } + + Write-Verbose "Encrypting the hard disks: $HardDisk...`n" + + $VMView = Get-View $VM + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $ProfileSpec = New-Object VMware.Vim.VirtualMachineDefinedProfileSpec + $ProfileSpec.ProfileId = $PolicyToBeUsed.Id + + $DeviceChanges = @() + + foreach ($Disk in $HardDisk) { + Write-Verbose "Attaching policy: $PolicyToBeUsed to $Disk`n" + $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $BackingSpec = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec + $DeviceChange.operation = "edit" + $DeviceChange.device = $Disk.extensiondata + $DeviceChange.Profile = $ProfileSpec + $BackingSpec.Crypto = $CryptoSpec + $DeviceChange.Backing = $BackingSpec + $DeviceChanges += $DeviceChange + } + + if ($DeviceChanges) { + $VMCfgSpec.deviceChange = $DeviceChanges + } + + return $VMView.ReconfigVM_Task($VMCfgSpec) + } +} + +Function Disable-VMEncryption { + <# + .SYNOPSIS + This cmdlet decrypts the specified VM. + + .DESCRIPTION + This cmdlet decrypts the specified VM. + + .PARAMETER VM + Specifies the VM you want to decrypt. + + .EXAMPLE + C:\PS>Get-VM -Name win2012 | Disable-VMEncryption + + Decrypts the VM Home and all encrypted disks. + + .EXAMPLE + C:\PS>$VM = Get-VM -Name win2012 + C:\PS>Disable-VMEncryption -VM $VM + + Decrypts the whole VM, including the encrypted disks. + + .NOTES + If the VM is not encrypted, the cmdlet quits. + + .NOTES + Author : Carrie Yang. + Author email : yangm@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + Process { + Write-Verbose "Checking if $VM is encrypted..." + if (!$VM.Encrypted) { + Write-Error "$VM is not encrypted.`n" + return + } + + Write-Verbose "Checking if $VM has no snapshots..." + if ($VM|Get-Snapshot) { + Write-Error "$VM has snapshots, it can not be decrypted!`n" + return + } + + Write-Verbose "Checking if $VM is powered off..." + if ($VM.powerstate -ne "PoweredOff") { + $ErrMsg = "The VM can only be decrypted when powered off, "+ + "but the current power state of $VM is $($VM.PowerState)!`n" + Write-Error $ErrMsg + return + } + + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $Profile = New-Object VMware.Vim.VirtualMachineEmptyProfileSpec + $DecryptCrypto = New-Object VMware.Vim.CryptoSpecDecrypt + $DisksToDecrypt = $VM|Get-HardDisk|Where {$_.Encrypted} + + $VMCfgSpec.VmProfile = $Profile + $VMCfgSpec.Crypto = $DecryptCrypto + + $DeviceChanges = @() + foreach ($Disk in $DisksToDecrypt) { + $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $DeviceChange.operation = "edit" + $DeviceChange.device = $Disk.extensiondata + $DeviceChange.Profile = $Profile + $DeviceChange.Backing = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec + $DeviceChange.Backing.Crypto = $DecryptCrypto + $DeviceChanges += $DeviceChange + } + + if ($Devicechanges) { + $VMCfgSpec.deviceChange = $Devicechanges + } + + return (Get-View $VM).ReconfigVM_Task($VMCfgSpec) + } +} + +Function Disable-VMDiskEncryption { + <# + .SYNOPSIS + This cmdlet decrypts the specified hard disks in a given VM. + + .DESCRIPTION + This cmdlet decrypts the specified hard disks in a given VM. + + .PARAMETER VM + Specifies the VM which the hard disks belong to. + + .PARAMETER HardDisk + Specifies the hard disks you want to decrypt. + + .EXAMPLE + C:\PS>$VM = Get-VM -Name win2012 + C:\PS>$HardDisk = $VM|Get-HardDisk|select -last 1 + C:\PS>Disable-VMDiskEncryption -VM $VM -HardDisk $HardDisk + + Decrypts the last hard disk in the VM. + + .NOTES + If the VM is not encrypted, the cmdlet quits. + + .NOTES + Author : Carrie Yang. + Author email : yangm@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.HardDisk[]] $HardDisk + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + Process { + Write-Verbose "Checking if $VM is encrypted..." + if (!$VM.Encrypted) { + Write-Error "$VM is not encrypted.`n" + return + } + + # Validate the hard disks + Write-Verbose "Checking the hard disks...`n" + ConfirmHardDiskIsValid -VM $VM -HardDisk $HardDisk + + $DisksToDecrypt = $HardDisk |Where {$_.Encrypted} + + if ($DisksToDecrypt.Length -eq 0) { + Write-Error "The provided disks are not encrypted.`n" + return + } + + Write-Verbose "Checking if $VM has no snapshots..." + if ($VM|Get-Snapshot) { + Write-Error "$VM has snapshots, it can not be decrypted!`n" + return + } + + Write-Verbose "Checking if $VM is powered off..." + if ($VM.powerstate -ne "PoweredOff") { + $ErrMsg = "The VM can only be decrypted when powered off, "+ + "but the current power state of $VM is $($VM.PowerState)!`n" + Write-Error $ErrMsg + return + } + + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $Profile = New-Object VMware.Vim.VirtualMachineEmptyProfileSpec + $DecryptCrypto = New-Object VMware.Vim.CryptoSpecDecrypt + + + $DeviceChanges = @() + foreach ($Disk in $DisksToDecrypt) { + $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $DeviceChange.operation = "edit" + $DeviceChange.device = $Disk.extensiondata + $DeviceChange.Profile = $Profile + $DeviceChange.Backing = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec + $DeviceChange.Backing.Crypto = $DecryptCrypto + $DeviceChanges += $DeviceChange + } + + $VMCfgSpec.deviceChange = $DeviceChanges + + return (Get-View $VM).ReconfigVM_Task($VMCfgSpec) + } +} + +Function Set-VMEncryptionKey { + <# + .SYNOPSIS + This cmdlet sets the encryption key of VM or hard disks. + + .DESCRIPTION + This cmdlet sets the encryption key of VM or hard disks. + + .PARAMETER VM + Specifies the VM you want to rekey. + + .PARAMETER KMSClusterId + Specifies the KMS clusterId you want to use for getting a new key for rekey operation. + + .PARAMETER Deep + When it's specified, both the key encryption key (KEK) and + the internal data encryption key (DEK) will be updated. + This is implemented through a full copy; It's a slow operation that + must be performed while the virtual machine is powered off. + A shallow key change will only update the KEK and the operation can be performed + while the virtual machine is running. + + .PARAMETER SkipHardDisks + Skip updating the hard disk keys. + + .EXAMPLE + C:\PS>Get-VM -Name win2012 | Set-VMEncryptionKey + + Rekeys the VM win2012 VM Home and all its disks. + + .EXAMPLE + C:\PS>$VM = Get-VM -Name win2012 + C:\PS>$VM|Set-VMEncryptionKey -SkipHardDisks + + Rekeys the VM Home only. + + .EXAMPLE + C:\PS>$VM = Get-VM -Name win2012 + C:\PS>$VM|Set-VMEncryptionKey -Deep + + Rekeys the VM Home and all its disks with Deep option. + + .EXAMPLE + C:\PS>$KMSCluster = Get-KMSCluster | select -last 1 + C:\PS>$VM = Get-VM -Name win2012 + C:\PS>$VM|Set-VMEncryptionKey -KMSClusterId $KMSCluster.Id -Deep + + Deep rekeys the VM Home and all its disks using a new key. + The key is generted from the KMS whose clusterId is $KMSCluster.Id. + + .NOTES + This cmdlet assumes there is already a KMS in vCenter Server. If VM is not encrypted, the cmdlet quits. + You should use Enable-VMEncryption cmdlet to encrypt the VM first. + + .NOTES + Author : Carrie Yang. + Author email : yangm@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$False)] + [String] $KMSClusterId, + + [Parameter(Mandatory=$False)] + [switch]$Deep = $FALSE, + + [Parameter(Mandatory=$False)] + [switch]$SkipHardDisks = $False + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + Process { + Write-Verbose "Checking if $VM is encrypted...`n" + if (!$VM.Encrypted) { + Write-Error "$VM is not encrypted." + return + } + + Write-Verbose "Checking if $VM has no snapshots...`n" + if ($VM|Get-Snapshot) { + Write-Error "$VM has snapshot, please remove all snapshots and try again!`n" + return + } + + if ($Deep) { + Write-Verbose "Checking if $VM powered off...`n" + if ($VM.powerstate -ne "PoweredOff") { + $ErrMsg = "The VM can only be recrypted when powered off, "+ + "but the current power state of $VM is $($VM.PowerState)!`n" + Write-Error $ErrMsg + return + } + } + + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $ProfileSpec = New-Object VMware.Vim.VirtualMachineDefinedProfileSpec + $CryptoSpec = New-Object VMware.Vim.CryptoSpecShallowRecrypt + + if ($Deep) { + $CryptoSpec = New-Object VMware.Vim.CryptoSpecDeepRecrypt + $VMPolicy = (Get-SpbmEntityConfiguration -VM $VM).StoragePolicy + $ProfileSpec.ProfileId = $VMPolicy.Id + $VMCfgSpec.VmProfile = $ProfileSpec + } + + # Generate a key from KMS + try { + $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId + } catch { + Throw "Key generation failed, make sure the KMS Cluster exists!`n" + } + $CryptoSpec.NewKeyId = $KeyResult.KeyId + $VMCfgSpec.Crypto = $CryptoSpec + + if (!$SkipHardDisks) { + $DisksToRecrypt = $VM|Get-HardDisk|Where {$_.Encrypted} + + $DeviceChanges = @() + foreach ($disk in $DisksToRecrypt) { + $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $DeviceChange.operation = "edit" + $DeviceChange.device = $Disk.extensiondata + if ($Deep) { + $DiskProfileSpec = New-Object VMware.Vim.VirtualMachineDefinedProfileSpec + $DiskProfileSpec.ProfileId = ($Disk|Get-SpbmEntityConfiguration).StoragePolicy.Id + $DeviceChange.Profile = $DiskProfileSpec + } + $DeviceChange.Backing = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec + $DeviceChange.Backing.Crypto = $CryptoSpec + $DeviceChanges += $DeviceChange + } + + if ($DeviceChanges.Length -gt 0) { + $VMCfgSpec.deviceChange = $DeviceChanges + } + } + + return (Get-View $VM).ReconfigVM_Task($VMCfgSpec) + } +} + +Function Set-VMDiskEncryptionKey { + <# + .SYNOPSIS + This cmdlet sets the encryption key of the hard disks in the VM. + + .DESCRIPTION + This cmdlet sets the encryption key of the hard disks in the VM. + + .PARAMETER VM + Specifies the VM from which you want to rekey its disks. + + .PARAMETER HardDisk + Specifies the hard disks you want to rekey. + + .PARAMETER KMSClusterId + Specifies the KMS clusterId you want to use for getting a new key for rekey operation. + + .PARAMETER Deep + When it's specified, both the key encryption key (KEK) and + the internal data encryption key (DEK) will be updated. + This is implemented through a full copy; It's a slow operation that + must be performed while the virtual machine is powered off. + A shallow key change will only update the KEK and the operation can be performed + while the virtual machine is running. + + .EXAMPLE + C:\PS>$VM = Get-VM -Name win2012 + C:\PS>$HardDisk = $VM|Get-HardDisk|select -last 2 + C:\PS>Set-VMDiskEncryptionKey -VM $VM -HardDisk $HardDisk + + Rekeys the last 2 hard disks in the VM. + + .EXAMPLE + C:\PS>$VM=Get-VM -Name win2012 + C:\PS>$HardDisk = get-vm $vm|Get-HardDisk|Select -last 2 + C:\PS>Set-VMDiskEncryptionKey -VM $VM -HardDisk $HardDisk -Deep + + Deep rekeys the last 2 hard disks in the VM. + + .EXAMPLE + C:\PS>$KMSCluster = Get-KMSCluster | select -last 1 + C:\PS>$VM = Get-VM -Name win2012 + C:\PS>$HardDisk = get-vm $vm|Get-HardDisk + C:\PS>$HardDisk|$Set-VMEncryptionKey -VM $VM -KMSClusterId $KMSCluster.Id -Deep + + Deep rekeys all the disks of the $VM using a new key. + The key is generted from the KMS whose clusterId is $KMSCluster.Id. + + .NOTES + This cmdlet assumes there is already a KMS in vCenter Server. + If VM is not encrypted, the cmdlet quits. + You should use Enable-VMEncryption cmdlet to encrypt the VM first. + + .NOTES + Author : Carrie Yang. + Author email : yangm@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.HardDisk[]] $HardDisk, + + [Parameter(Mandatory=$False)] + [String] $KMSClusterId, + + [Parameter(Mandatory=$False)] + [switch]$Deep = $FALSE + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + Process { + Write-Verbose "Checking if $VM is encrypted...`n" + if (!$VM.Encrypted) { + Write-Error "$VM is not encrypted." + return + } + + # Valid the hard disks + Write-Verbose "Checking the hard disks...`n" + ConfirmHardDiskIsValid -VM $VM -HardDisk $HardDisk + + Write-Verbose "Checking if $VM has no snapshots...`n" + if ($VM|Get-Snapshot) { + Write-Error "$VM has snapshot, please remove all snapshots and try again!`n" + return + } + + if ($Deep) { + Write-Verbose "Checking if $VM powered off...`n" + if ($VM.powerstate -ne "PoweredOff") { + $ErrMsg = "Deep rekey could be done only when VM powered off,"+ + "but current VM power state is: $($VM.powerstate)!`n" + Write-Error $ErrMsg + return + } + } + + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $CryptoSpec = New-Object VMware.Vim.CryptoSpecShallowRecrypt + if ($Deep) { + $CryptoSpec = New-Object VMware.Vim.CryptoSpecDeepRecrypt + } + + # Generate a key from KMS + try { + $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId + } catch { + Throw "Key generation failed, make sure the KMS Cluster exists!`n" + } + $CryptoSpec.NewKeyId = $KeyResult.KeyId + + $DeviceChanges = @() + foreach ($disk in $HardDisk) { + $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $DeviceChange.operation = "edit" + $DeviceChange.device = $Disk.extensiondata + if ($Deep) { + $ProfileSpec = New-Object VMware.Vim.VirtualMachineDefinedProfileSpec + $ProfileSpec.ProfileId = ($Disk|Get-SpbmEntityConfiguration).StoragePolicy.Id + $DeviceChange.Profile = $ProfileSpec + } + $DeviceChange.Backing = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec + $DeviceChange.Backing.Crypto = $CryptoSpec + $DeviceChanges += $DeviceChange + } + + $VMCfgSpec.deviceChange = $DeviceChanges + + return (Get-View $VM).ReconfigVM_Task($VMCfgSpec) + } +} + +Function Get-VMEncryptionInfo { + <# + .SYNOPSIS + This cmdlet gets the encryption information of VM and its disks. + + .DESCRIPTION + This cmdlet gets the encryption information of VM and its disks. + + .PARAMETER VM + Specifies the VM for which you want to retrieve the encryption information. + + .PARAMETER HardDisk + Specifies the hard disks for which you want to retrieve the encryption information. + + .EXAMPLE + C:\PS>Get-VM|Get-VMEncryptionInfo + + Retrieves all VM's encryption information. + + .EXAMPLE + C:\PS>Get-VMEncryptionInfo -VM $vm -HardDisk $HardDisks + + Retrieves only disks' encryption information. + + .NOTES + If $HardDisk is specified, then only the encryption information of the disks specified in $HardDisk is obtained. + Otherwise, all disks' encryption information of the specified VM is returned. + + .NOTES + Author : Carrie Yang. + Author email : yangm@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.HardDisk[]] $HardDisk + ) + + Process { + $DisksInfo = @() + + if ($HardDisk) { + # Validate the hard disks + Write-Verbose "Checking the hard disks...`n" + ConfirmHardDiskIsValid -VM $VM -HardDisk $HardDisk + } + + foreach ($DK in $HardDisk) { + $DKInfo = @{} + $DKInfo.index = $DK.ExtensionData.Key + $DKInfo.label = $DK.ExtensionData.DeviceInfo.Label + $diskSize = $DK.ExtensionData.CapacityInKB + $formattedSize = "{0:N0}" -f $diskSize + $DKInfo.summary = "$formattedSize KB" + $DKInfo.profile = ($DK|Get-SpbmEntityConfiguration).StoragePolicy + $DKInfo.fileName = $DK.Filename + $DKInfo.uuid = $DK.ExtensionData.Backing.Uuid + $DKInfo.keyId = $DK.ExtensionData.Backing.KeyId + $DKInfo.iofilter = $DK.ExtensionData.Iofilter + $DisksInfo += $DKInfo + } + + $VMInfo = @{} + $VMInfo.name = $VM.Name + $VMInfo.connectState = $VM.ExtensionData.Runtime.ConnectionState + $VMInfo.profile = ($VM | Get-SpbmEntityConfiguration).StoragePolicy + $VMInfo.keyId = $VM.ExtensionData.Config.KeyId + $VMInfo.disks = $DisksInfo + + return $VMInfo + } +} + +Function Get-EntityByCryptoKey { + <# + .SYNOPSIS + This cmdlet gets all the related objects in which it has the key associated. + + .DESCRIPTION + This cmdlet gets all the related objects in which it has the key associated. + + .PARAMETER KeyId + Specifies the KeyId string. + + .PARAMETER KMSClusterId + Specifies the KMSClusterId string. + + .PARAMETER SearchVMHosts + Specifies whether to search the VMHosts. + + .PARAMETER SearchVMs + Specifies whether to search the VMs. + + .PARAMETER SearchDisks + Specifies whether to search the HardDisks. + + .EXAMPLE + C:\PS>Get-EntityByCryptoKeyId -SearchVMHosts -KeyId 'keyId' + + Gets the VMHosts whose CryptoKeyId's KeyId matches exactly the 'keyId'. + + .EXAMPLE + C:\PS>Get-EntityByCryptoKeyId -SearchVMs -KMSClusterId 'clusterId' + + Gets the VMs whose CryptoKeyId's ProfileId.Id matches exactly the 'clusterId'. + + .EXAMPLE + C:\PS>Get-EntityByCryptoKey -SearchVMHosts -SearchVMs -KMSClusterId 'clusterId' + + Gets VMHosts and VMs whose CryptoKeyId's ProviderId.Id matches the 'clusterId'. + + .NOTES + At least one of the KeyId and KMSClusterId parameters is required. + If the SearchVMHosts, SearchVMs and SearchDisks all not specified, the cmdlet return $null. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$false,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [String] $keyId, + + [Parameter(Mandatory=$false,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [String] $KMSClusterId, + + [Parameter(Mandatory=$False)] + [switch] $SearchVMHosts, + + [Parameter(Mandatory=$False)] + [switch] $SearchVMs, + + [Parameter(Mandatory=$False)] + [switch] $SearchDisks + ) + + if (!$KeyId -and !$KMSClusterId) { + Throw "One of the keyId or KMSClusterId must be specified!`n" + } + + # The returned Items + $Entities = @{} + + # Find VMHosts + $CryptoSafeVMHosts = Get-VMHost|Where {$_.CryptoSafe} + + # Quit if no VMHosts found. + if (!$CryptoSafeVMHosts) { + Throw "No VMHosts enabled the CrytoState to Safe!`n" + } + + if ($SearchVMHosts) { + Write-Verbose "Starting to search VMHosts...`n" + $VMHostList = $CryptoSafeVMHosts| Where {$_.ExtensionData.Runtime.CryptoKeyId|MatchKeys -KeyId $KeyId -KMSClusterId $KMSClusterId} + $Entities.VMHostList = $VMHostList + } + + # Find the VMs which encrypted: Look for both VMHome and Disks + $VMs = Get-VM|Where {$_.Encrypted} + if ($SearchVMs) { + Write-Verbose "Starting to search VMs...`n" + $VMList = @() + $Disks = $VMs|Get-HardDisk|Where {$_.Encrypted} + $VMDiskList = $Disks|Where {$_.EncryptionKeyId|MatchKeys -KeyId $keyId -KMSClusterId $KMSClusterId} + + $VMList += $VMs|Where {$_.EncryptionKeyId|MatchKeys -KeyId $keyId -KMSClusterId $KMSClusterId} + $VMList += $VMDiskList.Parent + $VMList = $VMList|sort|Get-Unique + $Entities.VMList = $VMList + } + + # Find the Disks + if ($SearchDisks) { + Write-Verbose "Starting to search Disks...`n" + if ($SearchVMs) { + $DiskList = $VMDiskList + } else { + $Disks = $VMs|Get-HardDisk|Where {$_.Encrypted} + $DiskList = $Disks|Where {$_.EncryptionKeyId|MatchKeys -KeyId $keyId -KMSClusterId $KMSClusterId} + } + + $Entities.DiskList = $DiskList + } + + return $Entities +} + +Function New-KMServer { + <# + .SYNOPSIS + This cmdlet adds a Key Management Server. + + .DESCRIPTION + This cmdlet adds a Key Management Server to vCenter Server and verifies it. + + .PARAMETER KMServer + Specifies the Key Management Server IP address or FQDN. + + .PARAMETER KMSClusterId + Specifies the ID of the KMS cluster. KMSs with the same cluster ID are in one cluster and provide the same keys for redundancy. + + .PARAMETER UserName + Specifies user name to authenticate to the KMS. + + .PARAMETER Password + Specifies password to authenticate to the KMS. + + .PARAMETER Name + Specifies the name of the KMS. + + .PARAMETER Port + Specifies the port of the KMS. + + .PARAMETER ProxyServer + Specifies the address of the proxy server. + + .PARAMETER ProxyPort + Specifies the port of the proxy server. + + .PARAMETER Protocol + Specifies the KMS library protocol handler, for example KMS1. + + .EXAMPLE + C:\PS>New-KMServer -KMServer 1.1.1.1 -KMSClusterId clsName -UserName "YourKMSUserName" -Password '***' -Name "KMS1" + + Adds the Key Management Server 1.1.1.1 into vCenter with the cluster name 'clsname' and KMS name 'KMS1'. + + .NOTES + This cmdlet only supports PyKMIP Server. For other KMS vendors, modify the script accordingly. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True)] + [String]$KMServer, + + [Parameter(Mandatory=$True,ValueFromPipeline=$True)] + [String]$KMSClusterId, + + [Parameter(Mandatory=$False)] + [String] $UserName, + + [Parameter(Mandatory=$True,ValueFromPipeline=$True)] + [String] $Name, + + [Parameter(Mandatory=$False)] + [String] $Password, + + [Parameter(Mandatory=$False)] + [Int] $Port=5696, + + [Parameter(Mandatory=$False)] + [String] $ProxyServer, + + [Parameter(Mandatory=$False)] + [Int] $ProxyPort, + + [Parameter(Mandatory=$False)] + [String] $Protocol + ) + + Begin { + write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Add-KeyManagementServer instead" + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + + # Get the cryptoManager of vCenter Server + $CM = GetCryptoManager + } + + Process { + if ([string]::IsNullOrWhiteSpace($KMSClusterId)) { + Write-Error "The KMSClusterId parameter is mandatory, please specify a valid value!`n" + return + } + + if ([string]::IsNullOrWhiteSpace($KMServer)) { + Write-Error "The KMServer parameter is mandatory, please specify a valid value!`n" + return + } + + if ([string]::IsNullOrWhiteSpace($Name)) { + Write-Error "The KMSName parameter is mandatory. Please specify a valid value!`n" + return + } + + Write-Verbose "Starting to add Key Management Server: $KMServer......`n" + # Construct KMServerInfo and Spec + $KMServerInfo = New-Object VMware.Vim.KmipServerInfo + $KMServerSpec = New-Object VMware.Vim.KmipServerSpec + $KMServerInfo.Address = $KMServer + $KMServerInfo.Name = $Name + + if ($UserName) { + $KMServerInfo.UserName = $UserName + } + + if ($KMSPassword) { + $KMServerSpec.Password = $Password + } + + if ($Port) { + $KMServerInfo.Port = $Port + } + + if ($ProxyServer) { + $KMServerInfo.ProxyAddress = $ProxyServer + } + + if ($ProxyPort) { + $KMServerInfo.ProxyPort = $ProxyPort + } + + if ($Protocol) { + $KMServerInfo.Protocol = $Protocol + } + + $ProviderID = New-Object VMware.Vim.KeyProviderId + $ProviderID.Id = $KMSClusterId + $KMServerSpec.ClusterId = $ProviderID + $KMServerSpec.Info = $KMServerInfo + + Write-Verbose "Registering $KMServer to vCenter Server....`n" + + try { + $CM.RegisterKmipServer($KMServerSpec) + } catch { + Write-Error "Exception: $_ !" + return + } + + Write-Verbose "Establishing trust between vCenter Server and the Key Management Server: $KMServer`n" + try { + $KMServerCert = $CM.RetrieveKmipServerCert($providerID,$KMServerInfo) + $CM.UploadKmipServerCert($providerID,$KMServerCert.Certificate) + } catch { + Write-Error "Error occurred while retrieveing and uploading certification!`n" + return + } + + $CM.updateviewdata() + if (!(Get-DefaultKMSCluster) -and + ($CM.KmipServers|foreach {$_.servers}|foreach {$_.Address}) -contains $KMServer) { + Write-Verbose "No default Key Management Server yet. Marking $KMServer as default!`n" + Set-DefaultKMSCluster -KMSClusterId $ProviderID.Id + } + + Write-Verbose "Verifying KMS registration.....`n" + $CM.updateviewdata() + $KMServers = $CM.Kmipservers|where {($_.servers|foreach {$_.Address}) -contains $KMServer} + if ($KMServers) { + Write-Verbose "Key Management Server registered successfully!`n" + $KMServers + } else { + Write-Error "Key Management Server registration failed!`n" + } + } +} + +Function Remove-KMServer { + <# + .SYNOPSIS + This cmdlet removes a Key Management Server. + + .DESCRIPTION + This cmdlet removes a Key Management Server from vCenter Server. + + .PARAMETER Name + Specifies the name or alias of the Key Management Server. + + .PARAMETER KMSClusterId + Specifies the KMS cluster ID string to be used as Key Management Server cluster. + + .EXAMPLE + C:\PS>Remove-KMServer -KMSClusterId "ClusterIdString" -KMSName "KMServerName" + + Removes the KMS from vCenter Server which has the KMS name and KMS cluster ID. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True)] + [String]$KMSClusterId, + + [Parameter(Mandatory=$True)] + [String]$Name + ) + + Begin { + write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Remove-KeyManagementServer instead" + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + + # Get the cryptoManager of vCenter Server + $CM = GetCryptoManager + } + + Process { + if ([string]::IsNullOrWhiteSpace($Name) -Or + [string]::IsNullOrWhiteSpace($KMSClusterId)) { + $ErrMsg = "The KMSName and KMSClusterId parameters are mandatory "+ + "and should not be null or empty!`n" + Write-Error $ErrMsg + return + } + + $KMServers = $CM.KmipServers + if (!$KMServers) { + Write-Error "There are no Key Managerment Servers in vCenter Server!`n" + return + } + + if ($KMServers|Where { ($_.ClusterId.Id -eq $KMSClusterId) -and ($_.Servers|Where {$_.Name -eq $Name})}) { + #Start to remove the specified Km Server + try { + $ProviderID = New-Object VMware.Vim.KeyProviderId + $ProviderID.Id = $KMSClusterId + $CM.RemoveKmipServer($providerID, $Name) + } catch { + Write-Error "Exception: $_!`n" + return + } + } else { + $KMSNotFounErrMsg = "Cannot find the KMS with Name:$Name and KMS ClusterId:$KMSClusterId,"+ + "please make sure you specified correct parameters!`n" + Write-Error $KMSNotFounErrMsg + return + } + } +} + +Function Get-KMSCluster { + <# + .SYNOPSIS + This cmdlet retrieves all KMS clusters. + + .DESCRIPTION + This cmdlet retrieves all KMS clusters. + + .EXAMPLE + C:\PS>Get-KMSCluster + + Retrieves all KMS clusters. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Get-KmsCluster instead" + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + + # Get the cryptoManager of vCenter Server + $CM = GetCryptoManager + + # Get all KMS Clusters + return $CM.KmipServers.ClusterId +} + +Function Get-KMSClusterInfo { + <# + .SYNOPSIS + This cmdlet retrieves the KMS cluster information. + + .DESCRIPTION + This cmdlet retrieves the KMS cluster Information by providing the KMS cluster ID string. + + .PARAMETER KMSClusterId + Specifies the KMS cluster ID. + + .EXAMPLE + C:\PS>Get-KMSClusterInfo + + Retrieves all KMS cluster information. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [String] $KMSClusterId + ) + + Begin { + write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Get-KmsCluster instead" + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + + # Get the cryptoManager of vCenter Server + $CM = GetCryptoManager + } + + Process { + # Get all Km Clusters if no KMSClusterId specified + if (!$KMSClusterId) { + return $CM.KmipServers + } + return $CM.KmipServers|where {$_.ClusterId.Id -eq $KMSClusterId} + } +} + +Function Get-KMServerInfo { + <# + .SYNOPSIS + This cmdlet retireves the Key Management Servers' information. + + .DESCRIPTION + This cmdlet retireves the Key Management Servers' information by providing the KMS cluster ID string. + + .PARAMETER KMSClusterId + Specifies the KMS cluster ID. + + .EXAMPLE + C:\PS>Get-KMServerInfo + + Retrieves information about all Key Management Servers. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [String] $KMSClusterId + ) + + Begin { + write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Get-KeyManagementServer instead" + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + + # Get the cryptoManager of vCenter Server + $CM = GetCryptoManager + } + + Process { + # Get all KMS Info if no clusterId specified + if ($KMSClusterId) { + $FindCluster = (Get-KMSCluster).Contains($KMSClusterId) + if (!$FindCluster) { + Write-Error "Cannot find the specified KMS ClusterId in vCenter Server!" + return + } + + $ClsInfo = Get-KMSClusterInfo -KMSClusterId $KMSClusterId + + return $ClsInfo.Servers + } + + return $CM.KmipServers.Servers + } +} + +Function Get-KMServerStatus { + <# + .SYNOPSIS + This cmdlet retrieves the KMS status. + + .DESCRIPTION + This cmdlet retrieves the KMS status by providing the KMS cluster ID String + + .PARAMETER KMSClusterId + Specifies the KMS cluster ID from which to retrieve the servers' status. + + .EXAMPLE + C:\PS>Get-KMServerStatus -KMSClusterId 'ClusterIdString' + + Retrieves the specified KMS cluster 'ClusterIdString' server status. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [String] $KMSClusterId + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + + # Get the cryptoManager of vCenter Server + $CM = GetCryptoManager + } + + Process { + $ClusterInfo = @() + if ($KMSClusterId) { + # Quit if the ClusterID cannot be found + $FindCluster = (Get-KMSCluster).Contains($KMSClusterId) + if (!$FindCluster) { + Write-Error "Cannot find the specified KMS ClusterId in vCenter Server!" + return + } + + $ClsInfo = New-Object VMware.Vim.KmipClusterInfo + $ProviderId = New-Object VMware.Vim.KeyProviderId + $ProviderId.Id = $KMSClusterId + $ClsInfo.ClusterId = $providerId + $ClsInfo.Servers = (Get-KMSClusterInfo -KMSClusterId $KMSClusterId).Servers + $ClusterInfo += $ClsInfo + $KMSClsStatus = $CM.RetrieveKmipServersStatus($ClusterInfo) + } else { + $ClusterInfo = Get-KMSClusterInfo + $KMSClsStatus = $CM.RetrieveKmipServersStatus($ClusterInfo) + } + + if ($KMSClsStatus) { + return $KMSClsStatus + } else { + Write-Error "Failed to get the KMS status`n" + return $null + } + } +} + +Function Get-DefaultKMSCluster { + <# + .SYNOPSIS + This cmdlet retrieves the default KMS cluster. + + .DESCRIPTION + This cmdlet retrieves the default KMS cluster. + + .EXAMPLE + C:\PS>Get-DefaultKMSCluster + + Retrieves the default KMS cluster. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Get-KmsCluster instead" + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + + # Get the cryptoManager of vCenter Server + $CM = GetCryptoManager + + return ($CM.KmipServers|where {$_.UseAsDefault}).ClusterId.Id +} + +Function Set-DefaultKMSCluster { + <# + .SYNOPSIS + This cmdlet sets the provided KMS cluster as the default KMS cluster. + + .DESCRIPTION + This cmdlet sets the provided KMS cluster as the default KMS cluster. + + .PARAMETER KMSClusterId + Specifies KMS cluster ID which will be used to mark as default KMS cluster. + + .EXAMPLE + C:\PS>Set-DefaultKMSCluster -KMSClusterId 'ClusterIdString' + + Sets the KMS cluster whose cluster ID is 'ClusterIdString' as the default KMS cluster. + + .NOTES + Author : Baoyin Qiao. + Author email : bqiao@vmware.com + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True)] + [String] $KMSClusterId + ) + + write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Set-KmsCluster instead" + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + + # Get the cryptoManager of vCenter Server + $CM = GetCryptoManager + $ProviderId = New-Object VMware.Vim.KeyProviderId + $ProviderId.Id = $KMSClusterId + + $CM.MarkDefault($ProviderId) +} + +Function Set-VMCryptoUnlock { + <# + .SYNOPSIS + This cmdlet unlocks a locked vm + + .DESCRIPTION + This cmdlet unlocks a locked vm + + .PARAMETER VM + Specifies the VM you want to unlock + + .EXAMPLE + PS C:\> Get-VM |where {$_.locked}| Set-VMCryptoUnlock + + Unlock all locked vms + + .NOTES + Author : Fangying Zhang + Author email : fzhang@vmware.com + #> + + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]]$VM + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + Process { + foreach ($thisvm in $vm) { + if (!$thisvm.encrypted) { + write-warning "$thisvm is not encrypted, will skip $thisvm" + continue + } + if (!$thisvm.Locked) { + write-warning "$thisvm may not be locked!" + # $thisvm.locked could be false on old 6.5.0 build (bug 1931370), so do not skip $thisvm + } + write-verbose "try to CryptoUnlock $thisvm" + $thisvm.ExtensionData.CryptoUnlock() + } + } +} + +Function Add-Vtpm { + <# + .SYNOPSIS + This cmdlet adds a Virtual TPM to the specified VM. + + .DESCRIPTION + This cmdlet adds a Virtual TPM to the specified VM. + + .PARAMETER VM + Specifies the VM you want to add Virtual TPM to. + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Add-Vtpm $vm1 + + Encrypts $vm1's VM home and adds Virtual TPM + + .NOTES + If VM home is already encrypted, the cmdlet will add a Virtual TPM to the VM. + If VM home is not encrypted, VM home will be encrypted and Virtual TPM will be added. + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.operation = "add" + $deviceChange.device = new-object VMware.Vim.VirtualTPM + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } +} + +Function Remove-Vtpm { + <# + .SYNOPSIS + This cmdlet removes a Virtual TPM from the specified VM. + + .DESCRIPTION + This cmdlet removes a Virtual TPM from the specified VM. + + .PARAMETER VM + Specifies the VM you want to remove Virtual TPM from. + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Remove-Vtpm $vm1 + + .EXAMPLE + C:\PS>Get-VM -Name win2016 |Remove-Vtpm + + Remove Virtual TPM from VM named win2016 + + .NOTES + Removing VirtualTPM will render all encrypted data on this VM unrecoverable. + VM home encryption state will be returned to the original state before Virtual TPM is added + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding(SupportsShouldProcess=$true, ConfirmImpact = "High")] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + $message = "Removing Virtual TPM will render all encrypted data on this VM unrecoverable" + if ($PSCmdlet.ShouldProcess($message, $message + "`n Do you want to proceed", "WARNING")) { + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.operation = "remove" + $deviceChange.device = $vtpm + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } + } +} + +Function Get-VtpmCsr { + <# + .SYNOPSIS + This cmdlet gets certficate signing requests(CSR) from Virtual TPM. + + .DESCRIPTION + This cmdlet gets certficate signing requests(CSR) from Virtual TPM. + The CSR is a ComObject X509enrollment.CX509CertificateRequestPkcs10 + + .PARAMETER VM + Specifies the VM you want to get the CSRs Virtual TPM from. + + .PARAMETER KeyType [RSA | ECC] + Specify that only get CSR with public key RSA algorithm. + If none is specified, both CSR will get returned + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Get-VtpmCsr $vm1 -KeyType RSA + + .NOTES + Both RSA and ECC CSRs objects will be returned. If ECC or RSA is specified, + only the corresponding object will be returned + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$False)] + [String]$KeyType + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + # Check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contains a Virtual TPM" + return + } + + $CSRs = @() + foreach ($csrArray in $vtpm.EndorsementKeyCertificateSigningRequest) { + $csrString = [System.Convert]::ToBase64String($csrArray) + $csr = New-Object -ComObject X509enrollment.CX509CertificateRequestPkcs10 + + #decode a base64 string into a CSR object + $csr.InitializeDecode($csrString,6) + if ($keyType) { + if ($csr.PublicKey.Algorithm.FriendlyName -eq $KeyType){ + return $csr + } + } else { + $CSRs += $csr + } + } + return $CSRs + } +} + +Function Set-VtpmCert{ + <# + .SYNOPSIS + This cmdlet replaces certificates of Virtual TPM in the specified VM. + + .DESCRIPTION + This cmdlet replaces certificates to Virtual TPM in the specified VM. + + .PARAMETER VM + Specifies the VM with Virtual TPM where you want to replace the certificates to. + + .PARAMETER Cert + Specifies the certificate object (System.Security.Cryptography.X509Certificates.X509Certificate) + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Set-VtpmCert $vm1 $certObj + + .EXAMPLE + C:\PS>Get-VM -Name win2016 | Set-VtpmCert $certObj + + Replace the appropriate certificate specified + + .NOTES + Only RSA or ECC certs will be overwritten + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM, + + [Parameter(Mandatory=$True)] + [System.Security.Cryptography.X509Certificates.X509Certificate] $Cert + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + #check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contains a Virtual TPM" + return + } + + $certOid = New-Object System.Security.Cryptography.Oid($Cert.GetKeyAlgorithm()) + + # Check which certificate to overwrite + $certLocation = GetKeyIndex $vtpm.EndorsementKeyCertificate $certOid.FriendlyName + if ($certLocation -eq -1) { + Write-Error "No Certificate with Matching Algorithm $($certOid.FriendlyName) found" + return + } + + $vtpm.EndorsementKeyCertificate[$certLocation] = $cert.GetRawCertData() + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.Operation = "edit" + $deviceChange.Device = $vtpm + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } +} + +Function Get-VtpmCert{ + <# + .SYNOPSIS + This cmdlet gets certificates of Virtual TPM in the specified VM. + + .DESCRIPTION + This cmdlet gets certificates of Virtual TPM in the specified VM. + + .PARAMETER VM + Specifies the VM with Virtual TPM where you want to get the certificate from + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>$certs = Get-VtpmCert $vm1 + + .NOTES + An array of certificate object (System.Security.Cryptography.X509Certificates.X509Certificate) + will be returned + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + # check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contain a Virtual TPM" + return + } + + $certs = @() + $vtpm.EndorsementKeyCertificate|foreach { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate + $cert.Import($_) + $certs += $cert + } + return $certs + } +} + +Function ConfirmIsVCenter{ + <# + .SYNOPSIS + This function confirms the connected VI server is vCenter Server. + + .DESCRIPTION + This function confirms the connected VI server is vCenter Server. + + .EXAMPLE + C:\PS>ConfirmIsVCenter + + Throws exception if the connected VIServer is not vCenter Server. + #> + + $SI = Get-View Serviceinstance + $VIType = $SI.Content.About.ApiType + + if ($VIType -ne "VirtualCenter") { + Throw "Operation requires vCenter Server!" + } +} + +Function ConfirmHardDiskIsValid { + <# + .SYNOPSIS + This function confirms the hard disks is valid. + + .DESCRIPTION + This function confirms the hard disks is valid. + + .PARAMETER VM + Specifies the VM which you want to used to validate against. + + .PARAMETER HardDisk + Specifies the hard disks which you want to use to validate. + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$True)] + [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.HardDisk[]] $HardDisk + ) + + $NonVMHardDisks = $HardDisk|Where {$_.Parent -ne $VM} + + if ($NonVMHardDisks.Length -ge 1) { + Throw "Some of the provided hard disks: $($NonVMHardDisks.FileName) do not belong to VM: $VM`n" + } +} + +Function MatchKeys { + <# + .SYNOPSIS + This function checks whether the given keys matched or not. + + .DESCRIPTION + This function checks whether the given keys matched or not with the provided KeyId or KMSClusterId. + + .PARAMETER KeyToMatch + Specifies the CryptoKey to match for. + + .PARAMETER KeyId + Specifies the keyId should be matched. + + .PARAMETER KMSClusterId + Specifies the KMSClusterId should be matched. + + .NOTES + Returns the true/false depends on the match result. + One of keyId or KMSClusterId parameter must be specified. + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True)] + [VMware.Vim.CryptoKeyId] $KeyToMatch, + + [Parameter(Mandatory=$false)] + [String] $KeyId, + + [Parameter(Mandatory=$false)] + [String] $KMSClusterId + ) + + Process { + if (!$KeyId -and !$KMSClusterId) { + Throw "One of the keyId or KMSClusterId must be specified!`n" + } + + $Match = $True + if ($KeyId -and ($KeyId -ne $KeyToMatch.KeyId)) { + $Match = $false + } + + if ($KMSClusterId) { + if (!$KeyToMatch.ProviderId) { + $Match = $false + } + + if ($KMSClusterId -ne $KeyToMatch.ProviderId.Id) { + $Match = $false + } + } + return $Match + } +} + +Function NewEncryptionKey { + <# + .SYNOPSIS + This function generates new encryption key from KMS. + + .DESCRIPTION + This function generates new encryption from KMS, if no KMSClusterId specified the default KMS will be used. + + .PARAMETER KMSClusterId + Specifies the KMS cluster id. + + .EXAMPLE + C:\PS>NewEncryptionKey -KMSClusterId 'ClusterIdString' + + Generates a new encryption key from the specified KMS which cluster id is 'ClusterIdString'. + #> + + Param ( + [Parameter(Mandatory=$False)] + [String]$KMSClusterId + ) + + # Confirm the connected VIServer is vCenter + ConfirmIsVCenter + + # Get the cryptoManager of vCenter Server + $CM = GetCryptoManager + $ProviderId = New-Object VMware.Vim.KeyProviderId + + Write-Verbose "Generate a CryptoKey.`n" + if ($KMSClusterId) { + $ProviderId.Id = $KMSClusterId + } else { + $ProviderId = $null + } + + $KeyResult = $CM.GenerateKey($ProviderId) + if (!$keyResult.Success) { + Throw "Key generation failed, make sure the KMS Cluster exists!`n" + } + return $KeyResult +} + +Function GetCryptoManager { + <# + .SYNOPSIS + This function retrieves the cryptoManager according to the given type. + + .DESCRIPTION + This function retrieves the cryptoManager according to the given type. + + .PARAMETER Type + Specifies the type of CryptoManager instance to get, the default value is KMS. + + .EXAMPLE + C:\PS>GetCryptoManager -Type "CryptoManagerKmip" + + Retrieves the 'CryptoManagerKmip' type CryptoManager. + #> + + Param ( + [Parameter(Mandatory=$false)] + [String] $Type + ) + + Process { + $SI = Get-View Serviceinstance + $CM = Get-View $SI.Content.CryptoManager + $cryptoMgrType = $CM.GetType().Name + + if (!$Type) { + # As the type is not cared, so return the CM directly + return $CM + } + if ($cryptoMgrType -eq $Type) { + return $CM + } + + Throw "Failed to get CryptoManager instance of the required type {$Type}!" + } +} + +Function GetKeyIndex{ + <# + .SYNOPSIS + This cmdlet returns the index to the key with a matching algorithm as the KeyType parameter + + .DESCRIPTION + This cmdlet returns the index to the key with a matching algorithm as the KeyType parameter + + .PARAMETER Certs + Specifies the list of certificats. Expected format is byte[][] + + .PARAMETER KeyType + Specifies the keytype to search for + + .EXAMPLE + C:\PS>$keyIndex = GetKeyIndex $Certs RSA + C:\PS>$keyIndex = GetKeyIndex $Certs ECC + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True)] + [byte[][]] $Certs, + + [Parameter(Mandatory=$True)] + [String] $KeyType + ) + process { + for ($i=0;$i -lt $Certs.Length; $i++) { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate + $cert.Import($Certs.Get($i)) + $certType = New-Object System.Security.Cryptography.Oid($cert.GetKeyAlgorithm()) + if ( $certType.FriendlyName -eq $keyType) { + return $i + } + } + return -1 + } +} + +Export-ModuleMember *-* +======= # Script Module : VMware.VMEncryption # Version : 1.1 @@ -2038,4 +4416,4 @@ Function GetCryptoManager { } } -Export-ModuleMember *-* +Export-ModuleMember *-* \ No newline at end of file From de1197d0e65f252d68313ae33fb49d71dfea3d88 Mon Sep 17 00:00:00 2001 From: Chong Yeo Date: Wed, 23 May 2018 11:49:33 -0700 Subject: [PATCH 02/50] Revert "1. Add the following Cmdlets for vTPM Support" This reverts commit 8dbea3ac244958fcf1b502dfb999a86e12aec7e3. Reverting because there were some merge conflicts that got away. --- .../VMware.VMEncryption.psd1 | 2 +- .../VMware.VMEncryption.psm1 | 2380 +---------------- 2 files changed, 2 insertions(+), 2380 deletions(-) diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 index aa83854..95b678f 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 @@ -12,7 +12,7 @@ # RootModule = '' # Version number of this module. -ModuleVersion = '1.2' +ModuleVersion = '1.1' # ID used to uniquely identify this module GUID = 'f9592e48-6cd3-494e-891b-ee10ee9f7018' diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 index 0211669..7752274 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 @@ -1,2381 +1,3 @@ -# Script Module : VMware.VMEncryption -# Version : 1.1 - -# Copyright © 2016 VMware, Inc. All Rights Reserved. - -# Permission is hereby granted, free of charge, to any person obtaining a copy of -# this software and associated documentation files (the "Software"), to deal in -# the Software without restriction, including without limitation the rights to -# use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies -# of the Software, and to permit persons to whom the Software is furnished to do -# so, subject to the following conditions: - -# The above copyright notice and this permission notice shall be included in all -# copies or substantial portions of the Software. - -# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -# SOFTWARE. - - -New-VIProperty -Name AESNIStatus -ObjectType VMHost -Value { - Param ($VMHost) - $FeatureCap = $VMHost.ExtensionData.Config.FeatureCapability - foreach ($Feature in $FeatureCap) { - if ($Feature.FeatureName -eq "cpuid.AES") { - ($Feature.Value -eq "1") - } - } -} -BasedOnExtensionProperty 'Config.FeatureCapability' -Force | Out-Null - -New-VIProperty -Name CryptoSafeSupported -ObjectType VMHost -Value { - Param ($VMHost) - $VMHost.ExtensionData.Runtime.CryptoState -ne $null -} -BasedOnExtensionProperty 'Runtime.CryptoState' -Force - -New-VIProperty -Name CryptoSafe -ObjectType VMHost -Value { - Param ($VMHost) - $VMHost.ExtensionData.Runtime.CryptoState -eq "safe" -} -BasedOnExtensionProperty 'Runtime.CryptoState' -Force - -New-VIProperty -Name Encrypted -ObjectType VirtualMachine -Value { - Param ($VM) - $VM.ExtensionData.Config.KeyId -ne $null -} -BasedOnExtensionProperty 'Config.KeyId' -Force | Out-Null - -New-VIProperty -Name EncryptionKeyId -ObjectType VirtualMachine -Value { - Param ($VM) - if ($VM.Encrypted) { - $VM.ExtensionData.Config.KeyId - } -} -BasedOnExtensionProperty 'Config.KeyId' -Force | Out-Null - -New-VIProperty -Name Locked -ObjectType VirtualMachine -Value { - Param ($VM) - if ($vm.ExtensionData.Runtime.CryptoState) { - $vm.ExtensionData.Runtime.CryptoState -eq "locked" - } - else { - ($vm.extensiondata.Runtime.ConnectionState -eq "invalid") -and ($vm.extensiondata.Config.KeyId) - } -} -BasedOnExtensionProperty 'Runtime.CryptoState', 'Runtime.ConnectionState','Config.KeyId' -Force | Out-Null - -New-VIProperty -Name vMotionEncryption -ObjectType VirtualMachine -Value { - Param ($VM) - $VM.ExtensionData.Config.MigrateEncryption -} -BasedOnExtensionProperty 'Config.MigrateEncryption' -Force | Out-Null - -New-VIProperty -Name KMSserver -ObjectType VirtualMachine -Value { - Param ($VM) - if ($VM.Encrypted) { - $VM.EncryptionKeyId.ProviderId.Id - } -} -BasedOnExtensionProperty 'Config.KeyId' -Force | Out-Null - -New-VIProperty -Name Encrypted -ObjectType HardDisk -Value { - Param ($hardDisk) - $hardDisk.ExtensionData.Backing.KeyId -ne $null -} -BasedOnExtensionProperty 'Backing.KeyId' -Force | Out-Null - -New-VIProperty -Name EncryptionKeyId -ObjectType HardDisk -Value { - Param ($Disk) - if ($Disk.Encrypted) { - $Disk.ExtensionData.Backing.KeyId - } -} -BasedOnExtensionProperty 'Backing.KeyId' -Force | Out-Null - -Function Enable-VMHostCryptoSafe { - <# - .SYNOPSIS - This cmdlet enables the VMHost's CryptoSate to safe. - - .DESCRIPTION - This cmdlet enables the VMHost's CryptoSate to safe. - - .PARAMETER VMHost - Specifies the VMHost you want to enable. - - .PARAMETER KMSClusterId - Specifies the KMS cluster ID which you want to use to generate the encrytion key. - - .EXAMPLE - C:\PS>$VMHost = Get-VMHost -name $VMHostName - C:\PS>Enable-VMHostCryptoSafe -VMHost $VMHost - - Enables the specified VMHost's CryptoSate to safe. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost] $VMHost, - - [Parameter(Mandatory=$False)] - [String] $KMSClusterId - ) - - Process { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - - if (!$VMHost.CryptoSafeSupported) { - Write-Error "The VMHost: $VMHost does not support CryptoSafe!`n" - return - } - - if ($VMHost.CryptoSafe) { - Write-Error "The VMHost: $VMHost CryptoSafe already enabled!`n" - return - } - - # Generate key from the specified KMS cluster - try { - $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId - } catch { - Throw "Key generation failed, make sure the KMS Cluster exists!`n" - } - - $VMHostView = Get-View $VMHost - $VMHostView.ConfigureCryptoKey($KeyResult.KeyId) - } -} - -Function Set-VMHostCryptoKey { - <# - .SYNOPSIS - This cmdlet changes the VMHost CryptoKey. - - .DESCRIPTION - This cmdlet changes the VMHost CryptoKey if VMHost is already in Crypto safe state. - - .PARAMETER VMHost - Specifies the VMHost whose CryptoKey you want to update. - - .PARAMETER KMSClusterId - Specifies the KMS cluster ID which you want to use to generate the encryption key. - - .EXAMPLE - C:\PS>$VMHost = Get-VMHost -Name $VMHostName - C:\PS>Set-VMHostCryptoKey -VMHost $VMHost - - Changes the VMHost CryptoKey to a new CryptoKey. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost] $VMHost, - - [Parameter(Mandatory=$False)] - [String] $KMSClusterId - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - - Process { - if (!$VMHost.CryptoSafeSupported) { - Write-Error "The VMHost: $VMHost does not support CryptoSafe!`n" - return - } - - if (!$VMHost.CryptoSafe) { - Write-Error "The VMHost: $VMHost has not enabled the CrytoSate to safe!" - return - } - - $VMHostView = Get-View $VMHost - $OldKey = $VMHostView.Runtime.CryptoKeyId - - # Generate key from the specified KMSCluster - try { - $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId - } catch { - Throw "Key generation failed, make sure the KMS Cluster exists!`n" - } - - try { - $VMHostView.ConfigureCryptoKey($KeyResult.KeyId) - Write-Verbose "Change Crypto Key on VMHost: $VMHost succeeded!`n" - } catch { - Write-Error "Change Crypto Key on VMHost: $VMHost failed.$_!`n" - return - } - - # Remove the old host key - Write-Verbose "Removing the old hostKey: $($OldKey.KeyId) on $VMHost...`n" - $VMHostCM = Get-View $VMHostView.ConfigManager.CryptoManager - $VMHostCM.RemoveKeys($OldKey, $true) - } -} - -Function Set-vMotionEncryptionConfig { - <# - .SYNOPSIS - This cmdlet sets the vMotionEncryption property of a VM. - - .DESCRIPTION - Use this function to set the vMotionEncryption settings for a VM. - The 'Encryption' parameter is set up with Tab-Complete for the available - options. - - .PARAMETER VM - Specifies the VM you want to set the vMotionEncryption property. - - .PARAMETER Encryption - Specifies the value you want to set to the vMotionEncryption property. - The Encryption options are: disabled, opportunistic, and required. - - .EXAMPLE - PS C:\> Get-VM | Set-vMotionEncryptionConfig -Encryption opportunistic - - Sets the vMotionEncryption of all the VMs - - .NOTES - Author : Brian Graf, Carrie Yang. - Author email : grafb@vmware.com, yangm@vmware.com - #> - - [CmdLetBinding()] - - param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM, - - [Parameter(Mandatory=$True)] - [ValidateSet("disabled", "opportunistic", "required")] - [String]$Encryption - ) - - process{ - if ($VM.vMotionEncryption -eq $Encryption) { - Write-Warning "The encrypted vMotion state is already $Encrypted, no need to change it." - return - } - - if ($VM.Encrypted) { - Write-Error "Cannot change encrypted vMotion state for an encrypted VM." - return - } - - $VMView = $VM | get-view - $Config = New-Object VMware.Vim.VirtualMachineConfigSpec - $Config.MigrateEncryption = New-Object VMware.Vim.VirtualMachineConfigSpecEncryptedVMotionModes - $Config.MigrateEncryption = $Encryption - - $VMView.ReconfigVM($config) - - $VM.ExtensionData.UpdateViewData() - $VM.vMotionEncryption - } -} - -Function Enable-VMEncryption { - <# - .SYNOPSIS - This cmdlet encrypts the specified VM. - - .DESCRIPTION - This cmdlet encrypts the specified VM. - - .PARAMETER SkipHardDisks - If specified, skips the encryption of the hard disks of the specified VM. - - .PARAMETER VM - Specifies the VM you want to encrypt. - - .PARAMETER Policy - Specifies the encryption policy you want to use. - - .PARAMETER KMSClusterId - Specifies the KMS clusterId you want to use to generate new key for encryption. - - .EXAMPLE - C:\PS>Get-VM -Name win2012|Enable-VMEncryption - - Encrypts the whole VM with default encryption policy. - - .EXAMPLE - C:\PS>$SP = Get-SpbmStoragePolicy -name "EncryptionPol" - C:\PS>Get-VM -Name win2012 |Enable-VMEncryption -Policy $SP -SkipHardDisks - - Encrypts the VM Home with the encryption policy 'EncryptionPol' and skips hard disks encryption. - - .NOTES - This cmdlet assumes there already is KMS defined in vCenter Server. - If VM Home is already encrypted, the cmdlet quits. - If VM Home is not encrypted, encrypt VM Home if SkipHardDisks specified. Otherwise encrypt the VM Home and VM-attached disks. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, - - [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)] - [VMware.VimAutomation.Storage.Types.V1.Spbm.SpbmStoragePolicy] $Policy, - - [Parameter(Mandatory=$False,ValueFromPipeline=$False,ValueFromPipelinebyPropertyName=$False)] - [String] $KMSClusterId, - - [Parameter(Mandatory=$False)] - [switch]$SkipHardDisks=$False - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - - Process { - # VM Home is already encrypted - if ($VM.Encrypted) { - $ErrMsg = "VM $VM is already encrypted, please use: "+ - "Enable-VMDiskEncryption if you want to "+ - "encrypt disks which not encrypted yet!`n" - Write-Error $ErrMsg - return - } - - Write-Verbose "Checking if the VMHost supports CryptoSafe...`n" - $VMhost = $VM|Get-VMHost - if (!$VMHost.CryptoSafeSupported) { - Write-Error "The VMHost: $VMHost does not support CryptoSafe.`n" - return - } - - Write-Verbose "Checking if $VM has no snapshots...`n" - if ($VM|Get-Snapshot) { - Write-Error "$VM has snapshots, please remove all snapshots and try again!`n" - return - } - - Write-Verbose "Checking if $VM powered off...`n" - if ($VM.PowerState -ne "PoweredOff") { - $ErrMsg = "The VM can only be encrypted when powered off, "+ - "but the current power state of $VM is $($VM.PowerState)!`n" - Write-Error $ErrMsg - return - } - - $PolicyToBeUsed = $null - $BuiltInEncPolicy = Get-SpbmStoragePolicy -Name "VM Encryption Policy" - - if ($Policy) { - # Known issue: If the provided policy is created/cloned from - # the default "VM Encryption Policy", - # Or When creating the policy you didn't select 'Custom', - # there will be null-valued Exception. - Write-Verbose "Checking if the provided policy: $Policy is an encryption policy`n" - if (($Policy.Name -ne "VM Encryption Policy") -and !$Policy.CommonRule.Capability.Category.Contains("ENCRYPTION")) { - Write-Error "The policy $Policy is not an encryption policy, exit!" - return - } - $PolicyToBeUsed = $Policy - } else { - Write-Verbose "No storage policy specified, try to use the built-in policy.`n" - if ($BuiltInEncPolicy) { - $PolicyToBeUsed = $BuiltInEncPolicy - } else { - Throw "The built-in policy does not exist, please use: New-SpbmStoragePolicy to create one first!`n" - } - } - - # Encrypt the VM disks if SkipHardDisk not specified - if (!$SkipHardDisks) { - $Disks = $VM|Get-HardDisk - } - - $VMView = Get-View $VM - $ProfileSpec = New-Object VMware.Vim.VirtualMachineDefinedProfileSpec - $ProfileSpec.ProfileId = $PolicyToBeUsed.Id - $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec - $VMCfgSpec.VmProfile = $ProfileSpec - - if ($KMSClusterId) { - # Generate a new key from KMS - try { - $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId - } catch { - Throw "Key generation failed, make sure the specified KMS Cluster exists!`n" - } - - $CryptoKeyId = $KeyResult.KeyId - $CryptoSpec = New-Object VMware.Vim.CryptoSpecEncrypt - $CryptoSpec.CryptoKeyId = $CryptoKeyId - $VMCfgSpec.Crypto = $CryptoSpec - } - - $DeviceChanges = @() - foreach ($Disk in $Disks) { - Write-Verbose "Attaching policy: $PolicyToBeUsed to $Disk`n" - $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec - $BackingSpec = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec - $DeviceChange.operation = "edit" - $DeviceChange.device = $Disk.extensiondata - $DeviceChange.Profile = $ProfileSpec - $BackingSpec.Crypto = $CryptoSpec - $DeviceChange.Backing = $BackingSpec - $DeviceChanges += $deviceChange - } - - if ($Devicechanges) { - $VMCfgSpec.deviceChange = $Devicechanges - } - - return $VMView.ReconfigVM_Task($VMCfgSpec) - } -} - -Function Enable-VMDiskEncryption { - <# - .SYNOPSIS - This cmdlet encrypts the specified hard disks. - - .DESCRIPTION - This cmdlet encrypts the specified hard disks. - - .PARAMETER VM - Specifies the VM whose hard disks you want to encrypt. - - .PARAMETER Policy - Specifies the encryption policy you want to use. - - .PARAMETER HardDisk - Specifies the hard disks you want to encrypt. - - .PARAMETER KMSClusterId - Specifies the KMS clusterId you want to use to generate new key for encryption. - - .EXAMPLE - C:\PS>$VM = Get-VM -Name win2012 - C:\PS>$VMDisks= $VM|Get-Harddisk|Select -last 2 - C:\PS>Enable-VMDiskEncryption -VM $VM -$HardDisk $VMDisks - - Encrypts the VM disks with the default encryption policy and use the VM encryption key. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, - - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.HardDisk[]] $HardDisk, - - [Parameter(Mandatory=$False)] - [VMware.VimAutomation.Storage.Types.V1.Spbm.SpbmStoragePolicy] $Policy, - - [Parameter(Mandatory=$False)] - [String] $KMSClusterId - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - - Process { - Write-Verbose "Checking if $VM is encrypted..." - if (!$VM.Encrypted) { - Write-Error "$VM is not encrypted, please use:Enable-VMEncryption to encrypt the VM.`n" - return - } - - # Validate the hard disks - Write-Verbose "Checking the hard disks...`n" - ConfirmHardDiskIsValid -VM $VM -HardDisk $HardDisk - - Write-Verbose "Checking if $VM has no snapshots..." - if ($VM|Get-Snapshot) { - Write-Error "$VM has snapshots, please remove all snapshots!`n" - return - } - - Write-Verbose "Checking if $VM is powered off..." - if ($VM.powerstate -ne "PoweredOff") { - $ErrMsg = "The VM can only be ecrypted when powered off, "+ - "but the current power state of $VM is $($VM.PowerState)!`n" - Write-Error $ErrMsg - return - } - - $PolicyToBeUsed = $null - - if ($Policy) { - # Known issue: If the provided policy is created/cloned from - # the default "VM Encryption Policy", - # Or When creating the policy you didn't select 'Custom', - # there will be null-valued Exception. - Write-Verbose "Checking if the provided policy: $Policy is an encryption policy`n" - if (($Policy.Name -ne "VM Encryption Policy") -and !$Policy.CommonRule.Capability.Category.Contains("ENCRYPTION")) { - Throw "The policy $Policy is not an encryption policy, exit!" - } - $PolicyToBeUsed = $Policy - } else { - Write-Verbose "No storage policy specified, try to use the VM Home policy.`n" - $PolicyToBeUsed = (Get-SpbmEntityConfiguration -VM $VM).StoragePolicy - if (!$PolicyToBeUsed) { - Write-Warning "The VM Home policy is not available, try to use the built-in policy.`n" - $BuiltInEncPolicy = Get-SpbmStoragePolicy -Name "VM Encryption Policy" - if ($BuiltInEncPolicy) { - $PolicyToBeUsed = $BuiltInEncPolicy - } else { - Throw "The built-in policy does not exist, please use: New-SpbmStoragePolicy to create one first!`n" - } - } - } - - # Specify the key used to encrypt disk - if ($KMSClusterId) { - # Generate a new key from KMS - try { - $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId - } catch { - Throw "Key generation failed, make sure the KMS Cluster exists!`n" - } - - $CryptoKeyId = $KeyResult.KeyId - $CryptoSpec = New-Object VMware.Vim.CryptoSpecEncrypt - $CryptoSpec.CryptoKeyId = $CryptoKeyId - } - - Write-Verbose "Encrypting the hard disks: $HardDisk...`n" - - $VMView = Get-View $VM - $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec - $ProfileSpec = New-Object VMware.Vim.VirtualMachineDefinedProfileSpec - $ProfileSpec.ProfileId = $PolicyToBeUsed.Id - - $DeviceChanges = @() - - foreach ($Disk in $HardDisk) { - Write-Verbose "Attaching policy: $PolicyToBeUsed to $Disk`n" - $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec - $BackingSpec = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec - $DeviceChange.operation = "edit" - $DeviceChange.device = $Disk.extensiondata - $DeviceChange.Profile = $ProfileSpec - $BackingSpec.Crypto = $CryptoSpec - $DeviceChange.Backing = $BackingSpec - $DeviceChanges += $DeviceChange - } - - if ($DeviceChanges) { - $VMCfgSpec.deviceChange = $DeviceChanges - } - - return $VMView.ReconfigVM_Task($VMCfgSpec) - } -} - -Function Disable-VMEncryption { - <# - .SYNOPSIS - This cmdlet decrypts the specified VM. - - .DESCRIPTION - This cmdlet decrypts the specified VM. - - .PARAMETER VM - Specifies the VM you want to decrypt. - - .EXAMPLE - C:\PS>Get-VM -Name win2012 | Disable-VMEncryption - - Decrypts the VM Home and all encrypted disks. - - .EXAMPLE - C:\PS>$VM = Get-VM -Name win2012 - C:\PS>Disable-VMEncryption -VM $VM - - Decrypts the whole VM, including the encrypted disks. - - .NOTES - If the VM is not encrypted, the cmdlet quits. - - .NOTES - Author : Carrie Yang. - Author email : yangm@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - - Process { - Write-Verbose "Checking if $VM is encrypted..." - if (!$VM.Encrypted) { - Write-Error "$VM is not encrypted.`n" - return - } - - Write-Verbose "Checking if $VM has no snapshots..." - if ($VM|Get-Snapshot) { - Write-Error "$VM has snapshots, it can not be decrypted!`n" - return - } - - Write-Verbose "Checking if $VM is powered off..." - if ($VM.powerstate -ne "PoweredOff") { - $ErrMsg = "The VM can only be decrypted when powered off, "+ - "but the current power state of $VM is $($VM.PowerState)!`n" - Write-Error $ErrMsg - return - } - - $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec - $Profile = New-Object VMware.Vim.VirtualMachineEmptyProfileSpec - $DecryptCrypto = New-Object VMware.Vim.CryptoSpecDecrypt - $DisksToDecrypt = $VM|Get-HardDisk|Where {$_.Encrypted} - - $VMCfgSpec.VmProfile = $Profile - $VMCfgSpec.Crypto = $DecryptCrypto - - $DeviceChanges = @() - foreach ($Disk in $DisksToDecrypt) { - $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec - $DeviceChange.operation = "edit" - $DeviceChange.device = $Disk.extensiondata - $DeviceChange.Profile = $Profile - $DeviceChange.Backing = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec - $DeviceChange.Backing.Crypto = $DecryptCrypto - $DeviceChanges += $DeviceChange - } - - if ($Devicechanges) { - $VMCfgSpec.deviceChange = $Devicechanges - } - - return (Get-View $VM).ReconfigVM_Task($VMCfgSpec) - } -} - -Function Disable-VMDiskEncryption { - <# - .SYNOPSIS - This cmdlet decrypts the specified hard disks in a given VM. - - .DESCRIPTION - This cmdlet decrypts the specified hard disks in a given VM. - - .PARAMETER VM - Specifies the VM which the hard disks belong to. - - .PARAMETER HardDisk - Specifies the hard disks you want to decrypt. - - .EXAMPLE - C:\PS>$VM = Get-VM -Name win2012 - C:\PS>$HardDisk = $VM|Get-HardDisk|select -last 1 - C:\PS>Disable-VMDiskEncryption -VM $VM -HardDisk $HardDisk - - Decrypts the last hard disk in the VM. - - .NOTES - If the VM is not encrypted, the cmdlet quits. - - .NOTES - Author : Carrie Yang. - Author email : yangm@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, - - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.HardDisk[]] $HardDisk - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - - Process { - Write-Verbose "Checking if $VM is encrypted..." - if (!$VM.Encrypted) { - Write-Error "$VM is not encrypted.`n" - return - } - - # Validate the hard disks - Write-Verbose "Checking the hard disks...`n" - ConfirmHardDiskIsValid -VM $VM -HardDisk $HardDisk - - $DisksToDecrypt = $HardDisk |Where {$_.Encrypted} - - if ($DisksToDecrypt.Length -eq 0) { - Write-Error "The provided disks are not encrypted.`n" - return - } - - Write-Verbose "Checking if $VM has no snapshots..." - if ($VM|Get-Snapshot) { - Write-Error "$VM has snapshots, it can not be decrypted!`n" - return - } - - Write-Verbose "Checking if $VM is powered off..." - if ($VM.powerstate -ne "PoweredOff") { - $ErrMsg = "The VM can only be decrypted when powered off, "+ - "but the current power state of $VM is $($VM.PowerState)!`n" - Write-Error $ErrMsg - return - } - - $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec - $Profile = New-Object VMware.Vim.VirtualMachineEmptyProfileSpec - $DecryptCrypto = New-Object VMware.Vim.CryptoSpecDecrypt - - - $DeviceChanges = @() - foreach ($Disk in $DisksToDecrypt) { - $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec - $DeviceChange.operation = "edit" - $DeviceChange.device = $Disk.extensiondata - $DeviceChange.Profile = $Profile - $DeviceChange.Backing = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec - $DeviceChange.Backing.Crypto = $DecryptCrypto - $DeviceChanges += $DeviceChange - } - - $VMCfgSpec.deviceChange = $DeviceChanges - - return (Get-View $VM).ReconfigVM_Task($VMCfgSpec) - } -} - -Function Set-VMEncryptionKey { - <# - .SYNOPSIS - This cmdlet sets the encryption key of VM or hard disks. - - .DESCRIPTION - This cmdlet sets the encryption key of VM or hard disks. - - .PARAMETER VM - Specifies the VM you want to rekey. - - .PARAMETER KMSClusterId - Specifies the KMS clusterId you want to use for getting a new key for rekey operation. - - .PARAMETER Deep - When it's specified, both the key encryption key (KEK) and - the internal data encryption key (DEK) will be updated. - This is implemented through a full copy; It's a slow operation that - must be performed while the virtual machine is powered off. - A shallow key change will only update the KEK and the operation can be performed - while the virtual machine is running. - - .PARAMETER SkipHardDisks - Skip updating the hard disk keys. - - .EXAMPLE - C:\PS>Get-VM -Name win2012 | Set-VMEncryptionKey - - Rekeys the VM win2012 VM Home and all its disks. - - .EXAMPLE - C:\PS>$VM = Get-VM -Name win2012 - C:\PS>$VM|Set-VMEncryptionKey -SkipHardDisks - - Rekeys the VM Home only. - - .EXAMPLE - C:\PS>$VM = Get-VM -Name win2012 - C:\PS>$VM|Set-VMEncryptionKey -Deep - - Rekeys the VM Home and all its disks with Deep option. - - .EXAMPLE - C:\PS>$KMSCluster = Get-KMSCluster | select -last 1 - C:\PS>$VM = Get-VM -Name win2012 - C:\PS>$VM|Set-VMEncryptionKey -KMSClusterId $KMSCluster.Id -Deep - - Deep rekeys the VM Home and all its disks using a new key. - The key is generted from the KMS whose clusterId is $KMSCluster.Id. - - .NOTES - This cmdlet assumes there is already a KMS in vCenter Server. If VM is not encrypted, the cmdlet quits. - You should use Enable-VMEncryption cmdlet to encrypt the VM first. - - .NOTES - Author : Carrie Yang. - Author email : yangm@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, - - [Parameter(Mandatory=$False)] - [String] $KMSClusterId, - - [Parameter(Mandatory=$False)] - [switch]$Deep = $FALSE, - - [Parameter(Mandatory=$False)] - [switch]$SkipHardDisks = $False - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - - Process { - Write-Verbose "Checking if $VM is encrypted...`n" - if (!$VM.Encrypted) { - Write-Error "$VM is not encrypted." - return - } - - Write-Verbose "Checking if $VM has no snapshots...`n" - if ($VM|Get-Snapshot) { - Write-Error "$VM has snapshot, please remove all snapshots and try again!`n" - return - } - - if ($Deep) { - Write-Verbose "Checking if $VM powered off...`n" - if ($VM.powerstate -ne "PoweredOff") { - $ErrMsg = "The VM can only be recrypted when powered off, "+ - "but the current power state of $VM is $($VM.PowerState)!`n" - Write-Error $ErrMsg - return - } - } - - $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec - $ProfileSpec = New-Object VMware.Vim.VirtualMachineDefinedProfileSpec - $CryptoSpec = New-Object VMware.Vim.CryptoSpecShallowRecrypt - - if ($Deep) { - $CryptoSpec = New-Object VMware.Vim.CryptoSpecDeepRecrypt - $VMPolicy = (Get-SpbmEntityConfiguration -VM $VM).StoragePolicy - $ProfileSpec.ProfileId = $VMPolicy.Id - $VMCfgSpec.VmProfile = $ProfileSpec - } - - # Generate a key from KMS - try { - $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId - } catch { - Throw "Key generation failed, make sure the KMS Cluster exists!`n" - } - $CryptoSpec.NewKeyId = $KeyResult.KeyId - $VMCfgSpec.Crypto = $CryptoSpec - - if (!$SkipHardDisks) { - $DisksToRecrypt = $VM|Get-HardDisk|Where {$_.Encrypted} - - $DeviceChanges = @() - foreach ($disk in $DisksToRecrypt) { - $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec - $DeviceChange.operation = "edit" - $DeviceChange.device = $Disk.extensiondata - if ($Deep) { - $DiskProfileSpec = New-Object VMware.Vim.VirtualMachineDefinedProfileSpec - $DiskProfileSpec.ProfileId = ($Disk|Get-SpbmEntityConfiguration).StoragePolicy.Id - $DeviceChange.Profile = $DiskProfileSpec - } - $DeviceChange.Backing = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec - $DeviceChange.Backing.Crypto = $CryptoSpec - $DeviceChanges += $DeviceChange - } - - if ($DeviceChanges.Length -gt 0) { - $VMCfgSpec.deviceChange = $DeviceChanges - } - } - - return (Get-View $VM).ReconfigVM_Task($VMCfgSpec) - } -} - -Function Set-VMDiskEncryptionKey { - <# - .SYNOPSIS - This cmdlet sets the encryption key of the hard disks in the VM. - - .DESCRIPTION - This cmdlet sets the encryption key of the hard disks in the VM. - - .PARAMETER VM - Specifies the VM from which you want to rekey its disks. - - .PARAMETER HardDisk - Specifies the hard disks you want to rekey. - - .PARAMETER KMSClusterId - Specifies the KMS clusterId you want to use for getting a new key for rekey operation. - - .PARAMETER Deep - When it's specified, both the key encryption key (KEK) and - the internal data encryption key (DEK) will be updated. - This is implemented through a full copy; It's a slow operation that - must be performed while the virtual machine is powered off. - A shallow key change will only update the KEK and the operation can be performed - while the virtual machine is running. - - .EXAMPLE - C:\PS>$VM = Get-VM -Name win2012 - C:\PS>$HardDisk = $VM|Get-HardDisk|select -last 2 - C:\PS>Set-VMDiskEncryptionKey -VM $VM -HardDisk $HardDisk - - Rekeys the last 2 hard disks in the VM. - - .EXAMPLE - C:\PS>$VM=Get-VM -Name win2012 - C:\PS>$HardDisk = get-vm $vm|Get-HardDisk|Select -last 2 - C:\PS>Set-VMDiskEncryptionKey -VM $VM -HardDisk $HardDisk -Deep - - Deep rekeys the last 2 hard disks in the VM. - - .EXAMPLE - C:\PS>$KMSCluster = Get-KMSCluster | select -last 1 - C:\PS>$VM = Get-VM -Name win2012 - C:\PS>$HardDisk = get-vm $vm|Get-HardDisk - C:\PS>$HardDisk|$Set-VMEncryptionKey -VM $VM -KMSClusterId $KMSCluster.Id -Deep - - Deep rekeys all the disks of the $VM using a new key. - The key is generted from the KMS whose clusterId is $KMSCluster.Id. - - .NOTES - This cmdlet assumes there is already a KMS in vCenter Server. - If VM is not encrypted, the cmdlet quits. - You should use Enable-VMEncryption cmdlet to encrypt the VM first. - - .NOTES - Author : Carrie Yang. - Author email : yangm@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, - - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.HardDisk[]] $HardDisk, - - [Parameter(Mandatory=$False)] - [String] $KMSClusterId, - - [Parameter(Mandatory=$False)] - [switch]$Deep = $FALSE - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - - Process { - Write-Verbose "Checking if $VM is encrypted...`n" - if (!$VM.Encrypted) { - Write-Error "$VM is not encrypted." - return - } - - # Valid the hard disks - Write-Verbose "Checking the hard disks...`n" - ConfirmHardDiskIsValid -VM $VM -HardDisk $HardDisk - - Write-Verbose "Checking if $VM has no snapshots...`n" - if ($VM|Get-Snapshot) { - Write-Error "$VM has snapshot, please remove all snapshots and try again!`n" - return - } - - if ($Deep) { - Write-Verbose "Checking if $VM powered off...`n" - if ($VM.powerstate -ne "PoweredOff") { - $ErrMsg = "Deep rekey could be done only when VM powered off,"+ - "but current VM power state is: $($VM.powerstate)!`n" - Write-Error $ErrMsg - return - } - } - - $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec - $CryptoSpec = New-Object VMware.Vim.CryptoSpecShallowRecrypt - if ($Deep) { - $CryptoSpec = New-Object VMware.Vim.CryptoSpecDeepRecrypt - } - - # Generate a key from KMS - try { - $KeyResult = NewEncryptionKey -KMSClusterId $KMSClusterId - } catch { - Throw "Key generation failed, make sure the KMS Cluster exists!`n" - } - $CryptoSpec.NewKeyId = $KeyResult.KeyId - - $DeviceChanges = @() - foreach ($disk in $HardDisk) { - $DeviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec - $DeviceChange.operation = "edit" - $DeviceChange.device = $Disk.extensiondata - if ($Deep) { - $ProfileSpec = New-Object VMware.Vim.VirtualMachineDefinedProfileSpec - $ProfileSpec.ProfileId = ($Disk|Get-SpbmEntityConfiguration).StoragePolicy.Id - $DeviceChange.Profile = $ProfileSpec - } - $DeviceChange.Backing = New-Object VMware.Vim.VirtualDeviceConfigSpecBackingSpec - $DeviceChange.Backing.Crypto = $CryptoSpec - $DeviceChanges += $DeviceChange - } - - $VMCfgSpec.deviceChange = $DeviceChanges - - return (Get-View $VM).ReconfigVM_Task($VMCfgSpec) - } -} - -Function Get-VMEncryptionInfo { - <# - .SYNOPSIS - This cmdlet gets the encryption information of VM and its disks. - - .DESCRIPTION - This cmdlet gets the encryption information of VM and its disks. - - .PARAMETER VM - Specifies the VM for which you want to retrieve the encryption information. - - .PARAMETER HardDisk - Specifies the hard disks for which you want to retrieve the encryption information. - - .EXAMPLE - C:\PS>Get-VM|Get-VMEncryptionInfo - - Retrieves all VM's encryption information. - - .EXAMPLE - C:\PS>Get-VMEncryptionInfo -VM $vm -HardDisk $HardDisks - - Retrieves only disks' encryption information. - - .NOTES - If $HardDisk is specified, then only the encryption information of the disks specified in $HardDisk is obtained. - Otherwise, all disks' encryption information of the specified VM is returned. - - .NOTES - Author : Carrie Yang. - Author email : yangm@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, - - [Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.HardDisk[]] $HardDisk - ) - - Process { - $DisksInfo = @() - - if ($HardDisk) { - # Validate the hard disks - Write-Verbose "Checking the hard disks...`n" - ConfirmHardDiskIsValid -VM $VM -HardDisk $HardDisk - } - - foreach ($DK in $HardDisk) { - $DKInfo = @{} - $DKInfo.index = $DK.ExtensionData.Key - $DKInfo.label = $DK.ExtensionData.DeviceInfo.Label - $diskSize = $DK.ExtensionData.CapacityInKB - $formattedSize = "{0:N0}" -f $diskSize - $DKInfo.summary = "$formattedSize KB" - $DKInfo.profile = ($DK|Get-SpbmEntityConfiguration).StoragePolicy - $DKInfo.fileName = $DK.Filename - $DKInfo.uuid = $DK.ExtensionData.Backing.Uuid - $DKInfo.keyId = $DK.ExtensionData.Backing.KeyId - $DKInfo.iofilter = $DK.ExtensionData.Iofilter - $DisksInfo += $DKInfo - } - - $VMInfo = @{} - $VMInfo.name = $VM.Name - $VMInfo.connectState = $VM.ExtensionData.Runtime.ConnectionState - $VMInfo.profile = ($VM | Get-SpbmEntityConfiguration).StoragePolicy - $VMInfo.keyId = $VM.ExtensionData.Config.KeyId - $VMInfo.disks = $DisksInfo - - return $VMInfo - } -} - -Function Get-EntityByCryptoKey { - <# - .SYNOPSIS - This cmdlet gets all the related objects in which it has the key associated. - - .DESCRIPTION - This cmdlet gets all the related objects in which it has the key associated. - - .PARAMETER KeyId - Specifies the KeyId string. - - .PARAMETER KMSClusterId - Specifies the KMSClusterId string. - - .PARAMETER SearchVMHosts - Specifies whether to search the VMHosts. - - .PARAMETER SearchVMs - Specifies whether to search the VMs. - - .PARAMETER SearchDisks - Specifies whether to search the HardDisks. - - .EXAMPLE - C:\PS>Get-EntityByCryptoKeyId -SearchVMHosts -KeyId 'keyId' - - Gets the VMHosts whose CryptoKeyId's KeyId matches exactly the 'keyId'. - - .EXAMPLE - C:\PS>Get-EntityByCryptoKeyId -SearchVMs -KMSClusterId 'clusterId' - - Gets the VMs whose CryptoKeyId's ProfileId.Id matches exactly the 'clusterId'. - - .EXAMPLE - C:\PS>Get-EntityByCryptoKey -SearchVMHosts -SearchVMs -KMSClusterId 'clusterId' - - Gets VMHosts and VMs whose CryptoKeyId's ProviderId.Id matches the 'clusterId'. - - .NOTES - At least one of the KeyId and KMSClusterId parameters is required. - If the SearchVMHosts, SearchVMs and SearchDisks all not specified, the cmdlet return $null. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$false,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [String] $keyId, - - [Parameter(Mandatory=$false,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [String] $KMSClusterId, - - [Parameter(Mandatory=$False)] - [switch] $SearchVMHosts, - - [Parameter(Mandatory=$False)] - [switch] $SearchVMs, - - [Parameter(Mandatory=$False)] - [switch] $SearchDisks - ) - - if (!$KeyId -and !$KMSClusterId) { - Throw "One of the keyId or KMSClusterId must be specified!`n" - } - - # The returned Items - $Entities = @{} - - # Find VMHosts - $CryptoSafeVMHosts = Get-VMHost|Where {$_.CryptoSafe} - - # Quit if no VMHosts found. - if (!$CryptoSafeVMHosts) { - Throw "No VMHosts enabled the CrytoState to Safe!`n" - } - - if ($SearchVMHosts) { - Write-Verbose "Starting to search VMHosts...`n" - $VMHostList = $CryptoSafeVMHosts| Where {$_.ExtensionData.Runtime.CryptoKeyId|MatchKeys -KeyId $KeyId -KMSClusterId $KMSClusterId} - $Entities.VMHostList = $VMHostList - } - - # Find the VMs which encrypted: Look for both VMHome and Disks - $VMs = Get-VM|Where {$_.Encrypted} - if ($SearchVMs) { - Write-Verbose "Starting to search VMs...`n" - $VMList = @() - $Disks = $VMs|Get-HardDisk|Where {$_.Encrypted} - $VMDiskList = $Disks|Where {$_.EncryptionKeyId|MatchKeys -KeyId $keyId -KMSClusterId $KMSClusterId} - - $VMList += $VMs|Where {$_.EncryptionKeyId|MatchKeys -KeyId $keyId -KMSClusterId $KMSClusterId} - $VMList += $VMDiskList.Parent - $VMList = $VMList|sort|Get-Unique - $Entities.VMList = $VMList - } - - # Find the Disks - if ($SearchDisks) { - Write-Verbose "Starting to search Disks...`n" - if ($SearchVMs) { - $DiskList = $VMDiskList - } else { - $Disks = $VMs|Get-HardDisk|Where {$_.Encrypted} - $DiskList = $Disks|Where {$_.EncryptionKeyId|MatchKeys -KeyId $keyId -KMSClusterId $KMSClusterId} - } - - $Entities.DiskList = $DiskList - } - - return $Entities -} - -Function New-KMServer { - <# - .SYNOPSIS - This cmdlet adds a Key Management Server. - - .DESCRIPTION - This cmdlet adds a Key Management Server to vCenter Server and verifies it. - - .PARAMETER KMServer - Specifies the Key Management Server IP address or FQDN. - - .PARAMETER KMSClusterId - Specifies the ID of the KMS cluster. KMSs with the same cluster ID are in one cluster and provide the same keys for redundancy. - - .PARAMETER UserName - Specifies user name to authenticate to the KMS. - - .PARAMETER Password - Specifies password to authenticate to the KMS. - - .PARAMETER Name - Specifies the name of the KMS. - - .PARAMETER Port - Specifies the port of the KMS. - - .PARAMETER ProxyServer - Specifies the address of the proxy server. - - .PARAMETER ProxyPort - Specifies the port of the proxy server. - - .PARAMETER Protocol - Specifies the KMS library protocol handler, for example KMS1. - - .EXAMPLE - C:\PS>New-KMServer -KMServer 1.1.1.1 -KMSClusterId clsName -UserName "YourKMSUserName" -Password '***' -Name "KMS1" - - Adds the Key Management Server 1.1.1.1 into vCenter with the cluster name 'clsname' and KMS name 'KMS1'. - - .NOTES - This cmdlet only supports PyKMIP Server. For other KMS vendors, modify the script accordingly. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True)] - [String]$KMServer, - - [Parameter(Mandatory=$True,ValueFromPipeline=$True)] - [String]$KMSClusterId, - - [Parameter(Mandatory=$False)] - [String] $UserName, - - [Parameter(Mandatory=$True,ValueFromPipeline=$True)] - [String] $Name, - - [Parameter(Mandatory=$False)] - [String] $Password, - - [Parameter(Mandatory=$False)] - [Int] $Port=5696, - - [Parameter(Mandatory=$False)] - [String] $ProxyServer, - - [Parameter(Mandatory=$False)] - [Int] $ProxyPort, - - [Parameter(Mandatory=$False)] - [String] $Protocol - ) - - Begin { - write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Add-KeyManagementServer instead" - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - - # Get the cryptoManager of vCenter Server - $CM = GetCryptoManager - } - - Process { - if ([string]::IsNullOrWhiteSpace($KMSClusterId)) { - Write-Error "The KMSClusterId parameter is mandatory, please specify a valid value!`n" - return - } - - if ([string]::IsNullOrWhiteSpace($KMServer)) { - Write-Error "The KMServer parameter is mandatory, please specify a valid value!`n" - return - } - - if ([string]::IsNullOrWhiteSpace($Name)) { - Write-Error "The KMSName parameter is mandatory. Please specify a valid value!`n" - return - } - - Write-Verbose "Starting to add Key Management Server: $KMServer......`n" - # Construct KMServerInfo and Spec - $KMServerInfo = New-Object VMware.Vim.KmipServerInfo - $KMServerSpec = New-Object VMware.Vim.KmipServerSpec - $KMServerInfo.Address = $KMServer - $KMServerInfo.Name = $Name - - if ($UserName) { - $KMServerInfo.UserName = $UserName - } - - if ($KMSPassword) { - $KMServerSpec.Password = $Password - } - - if ($Port) { - $KMServerInfo.Port = $Port - } - - if ($ProxyServer) { - $KMServerInfo.ProxyAddress = $ProxyServer - } - - if ($ProxyPort) { - $KMServerInfo.ProxyPort = $ProxyPort - } - - if ($Protocol) { - $KMServerInfo.Protocol = $Protocol - } - - $ProviderID = New-Object VMware.Vim.KeyProviderId - $ProviderID.Id = $KMSClusterId - $KMServerSpec.ClusterId = $ProviderID - $KMServerSpec.Info = $KMServerInfo - - Write-Verbose "Registering $KMServer to vCenter Server....`n" - - try { - $CM.RegisterKmipServer($KMServerSpec) - } catch { - Write-Error "Exception: $_ !" - return - } - - Write-Verbose "Establishing trust between vCenter Server and the Key Management Server: $KMServer`n" - try { - $KMServerCert = $CM.RetrieveKmipServerCert($providerID,$KMServerInfo) - $CM.UploadKmipServerCert($providerID,$KMServerCert.Certificate) - } catch { - Write-Error "Error occurred while retrieveing and uploading certification!`n" - return - } - - $CM.updateviewdata() - if (!(Get-DefaultKMSCluster) -and - ($CM.KmipServers|foreach {$_.servers}|foreach {$_.Address}) -contains $KMServer) { - Write-Verbose "No default Key Management Server yet. Marking $KMServer as default!`n" - Set-DefaultKMSCluster -KMSClusterId $ProviderID.Id - } - - Write-Verbose "Verifying KMS registration.....`n" - $CM.updateviewdata() - $KMServers = $CM.Kmipservers|where {($_.servers|foreach {$_.Address}) -contains $KMServer} - if ($KMServers) { - Write-Verbose "Key Management Server registered successfully!`n" - $KMServers - } else { - Write-Error "Key Management Server registration failed!`n" - } - } -} - -Function Remove-KMServer { - <# - .SYNOPSIS - This cmdlet removes a Key Management Server. - - .DESCRIPTION - This cmdlet removes a Key Management Server from vCenter Server. - - .PARAMETER Name - Specifies the name or alias of the Key Management Server. - - .PARAMETER KMSClusterId - Specifies the KMS cluster ID string to be used as Key Management Server cluster. - - .EXAMPLE - C:\PS>Remove-KMServer -KMSClusterId "ClusterIdString" -KMSName "KMServerName" - - Removes the KMS from vCenter Server which has the KMS name and KMS cluster ID. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True)] - [String]$KMSClusterId, - - [Parameter(Mandatory=$True)] - [String]$Name - ) - - Begin { - write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Remove-KeyManagementServer instead" - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - - # Get the cryptoManager of vCenter Server - $CM = GetCryptoManager - } - - Process { - if ([string]::IsNullOrWhiteSpace($Name) -Or - [string]::IsNullOrWhiteSpace($KMSClusterId)) { - $ErrMsg = "The KMSName and KMSClusterId parameters are mandatory "+ - "and should not be null or empty!`n" - Write-Error $ErrMsg - return - } - - $KMServers = $CM.KmipServers - if (!$KMServers) { - Write-Error "There are no Key Managerment Servers in vCenter Server!`n" - return - } - - if ($KMServers|Where { ($_.ClusterId.Id -eq $KMSClusterId) -and ($_.Servers|Where {$_.Name -eq $Name})}) { - #Start to remove the specified Km Server - try { - $ProviderID = New-Object VMware.Vim.KeyProviderId - $ProviderID.Id = $KMSClusterId - $CM.RemoveKmipServer($providerID, $Name) - } catch { - Write-Error "Exception: $_!`n" - return - } - } else { - $KMSNotFounErrMsg = "Cannot find the KMS with Name:$Name and KMS ClusterId:$KMSClusterId,"+ - "please make sure you specified correct parameters!`n" - Write-Error $KMSNotFounErrMsg - return - } - } -} - -Function Get-KMSCluster { - <# - .SYNOPSIS - This cmdlet retrieves all KMS clusters. - - .DESCRIPTION - This cmdlet retrieves all KMS clusters. - - .EXAMPLE - C:\PS>Get-KMSCluster - - Retrieves all KMS clusters. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Get-KmsCluster instead" - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - - # Get the cryptoManager of vCenter Server - $CM = GetCryptoManager - - # Get all KMS Clusters - return $CM.KmipServers.ClusterId -} - -Function Get-KMSClusterInfo { - <# - .SYNOPSIS - This cmdlet retrieves the KMS cluster information. - - .DESCRIPTION - This cmdlet retrieves the KMS cluster Information by providing the KMS cluster ID string. - - .PARAMETER KMSClusterId - Specifies the KMS cluster ID. - - .EXAMPLE - C:\PS>Get-KMSClusterInfo - - Retrieves all KMS cluster information. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [String] $KMSClusterId - ) - - Begin { - write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Get-KmsCluster instead" - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - - # Get the cryptoManager of vCenter Server - $CM = GetCryptoManager - } - - Process { - # Get all Km Clusters if no KMSClusterId specified - if (!$KMSClusterId) { - return $CM.KmipServers - } - return $CM.KmipServers|where {$_.ClusterId.Id -eq $KMSClusterId} - } -} - -Function Get-KMServerInfo { - <# - .SYNOPSIS - This cmdlet retireves the Key Management Servers' information. - - .DESCRIPTION - This cmdlet retireves the Key Management Servers' information by providing the KMS cluster ID string. - - .PARAMETER KMSClusterId - Specifies the KMS cluster ID. - - .EXAMPLE - C:\PS>Get-KMServerInfo - - Retrieves information about all Key Management Servers. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [String] $KMSClusterId - ) - - Begin { - write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Get-KeyManagementServer instead" - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - - # Get the cryptoManager of vCenter Server - $CM = GetCryptoManager - } - - Process { - # Get all KMS Info if no clusterId specified - if ($KMSClusterId) { - $FindCluster = (Get-KMSCluster).Contains($KMSClusterId) - if (!$FindCluster) { - Write-Error "Cannot find the specified KMS ClusterId in vCenter Server!" - return - } - - $ClsInfo = Get-KMSClusterInfo -KMSClusterId $KMSClusterId - - return $ClsInfo.Servers - } - - return $CM.KmipServers.Servers - } -} - -Function Get-KMServerStatus { - <# - .SYNOPSIS - This cmdlet retrieves the KMS status. - - .DESCRIPTION - This cmdlet retrieves the KMS status by providing the KMS cluster ID String - - .PARAMETER KMSClusterId - Specifies the KMS cluster ID from which to retrieve the servers' status. - - .EXAMPLE - C:\PS>Get-KMServerStatus -KMSClusterId 'ClusterIdString' - - Retrieves the specified KMS cluster 'ClusterIdString' server status. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$False,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [String] $KMSClusterId - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - - # Get the cryptoManager of vCenter Server - $CM = GetCryptoManager - } - - Process { - $ClusterInfo = @() - if ($KMSClusterId) { - # Quit if the ClusterID cannot be found - $FindCluster = (Get-KMSCluster).Contains($KMSClusterId) - if (!$FindCluster) { - Write-Error "Cannot find the specified KMS ClusterId in vCenter Server!" - return - } - - $ClsInfo = New-Object VMware.Vim.KmipClusterInfo - $ProviderId = New-Object VMware.Vim.KeyProviderId - $ProviderId.Id = $KMSClusterId - $ClsInfo.ClusterId = $providerId - $ClsInfo.Servers = (Get-KMSClusterInfo -KMSClusterId $KMSClusterId).Servers - $ClusterInfo += $ClsInfo - $KMSClsStatus = $CM.RetrieveKmipServersStatus($ClusterInfo) - } else { - $ClusterInfo = Get-KMSClusterInfo - $KMSClsStatus = $CM.RetrieveKmipServersStatus($ClusterInfo) - } - - if ($KMSClsStatus) { - return $KMSClsStatus - } else { - Write-Error "Failed to get the KMS status`n" - return $null - } - } -} - -Function Get-DefaultKMSCluster { - <# - .SYNOPSIS - This cmdlet retrieves the default KMS cluster. - - .DESCRIPTION - This cmdlet retrieves the default KMS cluster. - - .EXAMPLE - C:\PS>Get-DefaultKMSCluster - - Retrieves the default KMS cluster. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Get-KmsCluster instead" - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - - # Get the cryptoManager of vCenter Server - $CM = GetCryptoManager - - return ($CM.KmipServers|where {$_.UseAsDefault}).ClusterId.Id -} - -Function Set-DefaultKMSCluster { - <# - .SYNOPSIS - This cmdlet sets the provided KMS cluster as the default KMS cluster. - - .DESCRIPTION - This cmdlet sets the provided KMS cluster as the default KMS cluster. - - .PARAMETER KMSClusterId - Specifies KMS cluster ID which will be used to mark as default KMS cluster. - - .EXAMPLE - C:\PS>Set-DefaultKMSCluster -KMSClusterId 'ClusterIdString' - - Sets the KMS cluster whose cluster ID is 'ClusterIdString' as the default KMS cluster. - - .NOTES - Author : Baoyin Qiao. - Author email : bqiao@vmware.com - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True)] - [String] $KMSClusterId - ) - - write-warning "This cmdlet is deprecated and will be removed in future release. Use VMware.VimAutomation.Storage\Set-KmsCluster instead" - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - - # Get the cryptoManager of vCenter Server - $CM = GetCryptoManager - $ProviderId = New-Object VMware.Vim.KeyProviderId - $ProviderId.Id = $KMSClusterId - - $CM.MarkDefault($ProviderId) -} - -Function Set-VMCryptoUnlock { - <# - .SYNOPSIS - This cmdlet unlocks a locked vm - - .DESCRIPTION - This cmdlet unlocks a locked vm - - .PARAMETER VM - Specifies the VM you want to unlock - - .EXAMPLE - PS C:\> Get-VM |where {$_.locked}| Set-VMCryptoUnlock - - Unlock all locked vms - - .NOTES - Author : Fangying Zhang - Author email : fzhang@vmware.com - #> - - [CmdLetBinding()] - - param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]]$VM - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - - Process { - foreach ($thisvm in $vm) { - if (!$thisvm.encrypted) { - write-warning "$thisvm is not encrypted, will skip $thisvm" - continue - } - if (!$thisvm.Locked) { - write-warning "$thisvm may not be locked!" - # $thisvm.locked could be false on old 6.5.0 build (bug 1931370), so do not skip $thisvm - } - write-verbose "try to CryptoUnlock $thisvm" - $thisvm.ExtensionData.CryptoUnlock() - } - } -} - -Function Add-Vtpm { - <# - .SYNOPSIS - This cmdlet adds a Virtual TPM to the specified VM. - - .DESCRIPTION - This cmdlet adds a Virtual TPM to the specified VM. - - .PARAMETER VM - Specifies the VM you want to add Virtual TPM to. - - .EXAMPLE - C:\PS>$vm1 = Get-VM -Name win2016 - C:\PS>Add-Vtpm $vm1 - - Encrypts $vm1's VM home and adds Virtual TPM - - .NOTES - If VM home is already encrypted, the cmdlet will add a Virtual TPM to the VM. - If VM home is not encrypted, VM home will be encrypted and Virtual TPM will be added. - - .NOTES - Author : Chong Yeo. - Author email : cyeo@vmware.com - #> - [CmdLetBinding()] - - param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - Process { - $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec - $deviceChange.operation = "add" - $deviceChange.device = new-object VMware.Vim.VirtualTPM - $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec - $VMCfgSpec.DeviceChange = $deviceChange - - return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) - } -} - -Function Remove-Vtpm { - <# - .SYNOPSIS - This cmdlet removes a Virtual TPM from the specified VM. - - .DESCRIPTION - This cmdlet removes a Virtual TPM from the specified VM. - - .PARAMETER VM - Specifies the VM you want to remove Virtual TPM from. - - .EXAMPLE - C:\PS>$vm1 = Get-VM -Name win2016 - C:\PS>Remove-Vtpm $vm1 - - .EXAMPLE - C:\PS>Get-VM -Name win2016 |Remove-Vtpm - - Remove Virtual TPM from VM named win2016 - - .NOTES - Removing VirtualTPM will render all encrypted data on this VM unrecoverable. - VM home encryption state will be returned to the original state before Virtual TPM is added - - .NOTES - Author : Chong Yeo. - Author email : cyeo@vmware.com - #> - [CmdLetBinding(SupportsShouldProcess=$true, ConfirmImpact = "High")] - - param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - Process { - $message = "Removing Virtual TPM will render all encrypted data on this VM unrecoverable" - if ($PSCmdlet.ShouldProcess($message, $message + "`n Do you want to proceed", "WARNING")) { - $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec - $deviceChange.operation = "remove" - $deviceChange.device = $vtpm - $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec - $VMCfgSpec.DeviceChange = $deviceChange - return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) - } - } -} - -Function Get-VtpmCsr { - <# - .SYNOPSIS - This cmdlet gets certficate signing requests(CSR) from Virtual TPM. - - .DESCRIPTION - This cmdlet gets certficate signing requests(CSR) from Virtual TPM. - The CSR is a ComObject X509enrollment.CX509CertificateRequestPkcs10 - - .PARAMETER VM - Specifies the VM you want to get the CSRs Virtual TPM from. - - .PARAMETER KeyType [RSA | ECC] - Specify that only get CSR with public key RSA algorithm. - If none is specified, both CSR will get returned - - .EXAMPLE - C:\PS>$vm1 = Get-VM -Name win2016 - C:\PS>Get-VtpmCsr $vm1 -KeyType RSA - - .NOTES - Both RSA and ECC CSRs objects will be returned. If ECC or RSA is specified, - only the corresponding object will be returned - - .NOTES - Author : Chong Yeo. - Author email : cyeo@vmware.com - #> - [CmdLetBinding()] - - param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, - - [Parameter(Mandatory=$False)] - [String]$KeyType - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - - process { - # Get vTPM from VM - $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} - - # Check if vTPM is already present - if (!$vtpm) { - Write-Error "$VM does not contains a Virtual TPM" - return - } - - $CSRs = @() - foreach ($csrArray in $vtpm.EndorsementKeyCertificateSigningRequest) { - $csrString = [System.Convert]::ToBase64String($csrArray) - $csr = New-Object -ComObject X509enrollment.CX509CertificateRequestPkcs10 - - #decode a base64 string into a CSR object - $csr.InitializeDecode($csrString,6) - if ($keyType) { - if ($csr.PublicKey.Algorithm.FriendlyName -eq $KeyType){ - return $csr - } - } else { - $CSRs += $csr - } - } - return $CSRs - } -} - -Function Set-VtpmCert{ - <# - .SYNOPSIS - This cmdlet replaces certificates of Virtual TPM in the specified VM. - - .DESCRIPTION - This cmdlet replaces certificates to Virtual TPM in the specified VM. - - .PARAMETER VM - Specifies the VM with Virtual TPM where you want to replace the certificates to. - - .PARAMETER Cert - Specifies the certificate object (System.Security.Cryptography.X509Certificates.X509Certificate) - - .EXAMPLE - C:\PS>$vm1 = Get-VM -Name win2016 - C:\PS>Set-VtpmCert $vm1 $certObj - - .EXAMPLE - C:\PS>Get-VM -Name win2016 | Set-VtpmCert $certObj - - Replace the appropriate certificate specified - - .NOTES - Only RSA or ECC certs will be overwritten - - .NOTES - Author : Chong Yeo. - Author email : cyeo@vmware.com - #> - [CmdLetBinding()] - - param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM, - - [Parameter(Mandatory=$True)] - [System.Security.Cryptography.X509Certificates.X509Certificate] $Cert - ) - - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - - process { - # Get vTPM from VM - $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} - - #check if vTPM is already present - if (!$vtpm) { - Write-Error "$VM does not contains a Virtual TPM" - return - } - - $certOid = New-Object System.Security.Cryptography.Oid($Cert.GetKeyAlgorithm()) - - # Check which certificate to overwrite - $certLocation = GetKeyIndex $vtpm.EndorsementKeyCertificate $certOid.FriendlyName - if ($certLocation -eq -1) { - Write-Error "No Certificate with Matching Algorithm $($certOid.FriendlyName) found" - return - } - - $vtpm.EndorsementKeyCertificate[$certLocation] = $cert.GetRawCertData() - $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec - $deviceChange.Operation = "edit" - $deviceChange.Device = $vtpm - $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec - $VMCfgSpec.DeviceChange = $deviceChange - - return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) - } -} - -Function Get-VtpmCert{ - <# - .SYNOPSIS - This cmdlet gets certificates of Virtual TPM in the specified VM. - - .DESCRIPTION - This cmdlet gets certificates of Virtual TPM in the specified VM. - - .PARAMETER VM - Specifies the VM with Virtual TPM where you want to get the certificate from - - .EXAMPLE - C:\PS>$vm1 = Get-VM -Name win2016 - C:\PS>$certs = Get-VtpmCert $vm1 - - .NOTES - An array of certificate object (System.Security.Cryptography.X509Certificates.X509Certificate) - will be returned - - .NOTES - Author : Chong Yeo. - Author email : cyeo@vmware.com - #> - [CmdLetBinding()] - param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM - ) - Begin { - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter - } - Process { - # Get vTPM from VM - $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} - - # check if vTPM is already present - if (!$vtpm) { - Write-Error "$VM does not contain a Virtual TPM" - return - } - - $certs = @() - $vtpm.EndorsementKeyCertificate|foreach { - $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate - $cert.Import($_) - $certs += $cert - } - return $certs - } -} - -Function ConfirmIsVCenter{ - <# - .SYNOPSIS - This function confirms the connected VI server is vCenter Server. - - .DESCRIPTION - This function confirms the connected VI server is vCenter Server. - - .EXAMPLE - C:\PS>ConfirmIsVCenter - - Throws exception if the connected VIServer is not vCenter Server. - #> - - $SI = Get-View Serviceinstance - $VIType = $SI.Content.About.ApiType - - if ($VIType -ne "VirtualCenter") { - Throw "Operation requires vCenter Server!" - } -} - -Function ConfirmHardDiskIsValid { - <# - .SYNOPSIS - This function confirms the hard disks is valid. - - .DESCRIPTION - This function confirms the hard disks is valid. - - .PARAMETER VM - Specifies the VM which you want to used to validate against. - - .PARAMETER HardDisk - Specifies the hard disks which you want to use to validate. - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True)] - [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, - - [Parameter(Mandatory=$True)] - [VMware.VimAutomation.ViCore.Types.V1.VirtualDevice.HardDisk[]] $HardDisk - ) - - $NonVMHardDisks = $HardDisk|Where {$_.Parent -ne $VM} - - if ($NonVMHardDisks.Length -ge 1) { - Throw "Some of the provided hard disks: $($NonVMHardDisks.FileName) do not belong to VM: $VM`n" - } -} - -Function MatchKeys { - <# - .SYNOPSIS - This function checks whether the given keys matched or not. - - .DESCRIPTION - This function checks whether the given keys matched or not with the provided KeyId or KMSClusterId. - - .PARAMETER KeyToMatch - Specifies the CryptoKey to match for. - - .PARAMETER KeyId - Specifies the keyId should be matched. - - .PARAMETER KMSClusterId - Specifies the KMSClusterId should be matched. - - .NOTES - Returns the true/false depends on the match result. - One of keyId or KMSClusterId parameter must be specified. - #> - - [CmdLetBinding()] - - Param ( - [Parameter(Mandatory=$True,ValueFromPipeline=$True)] - [VMware.Vim.CryptoKeyId] $KeyToMatch, - - [Parameter(Mandatory=$false)] - [String] $KeyId, - - [Parameter(Mandatory=$false)] - [String] $KMSClusterId - ) - - Process { - if (!$KeyId -and !$KMSClusterId) { - Throw "One of the keyId or KMSClusterId must be specified!`n" - } - - $Match = $True - if ($KeyId -and ($KeyId -ne $KeyToMatch.KeyId)) { - $Match = $false - } - - if ($KMSClusterId) { - if (!$KeyToMatch.ProviderId) { - $Match = $false - } - - if ($KMSClusterId -ne $KeyToMatch.ProviderId.Id) { - $Match = $false - } - } - return $Match - } -} - -Function NewEncryptionKey { - <# - .SYNOPSIS - This function generates new encryption key from KMS. - - .DESCRIPTION - This function generates new encryption from KMS, if no KMSClusterId specified the default KMS will be used. - - .PARAMETER KMSClusterId - Specifies the KMS cluster id. - - .EXAMPLE - C:\PS>NewEncryptionKey -KMSClusterId 'ClusterIdString' - - Generates a new encryption key from the specified KMS which cluster id is 'ClusterIdString'. - #> - - Param ( - [Parameter(Mandatory=$False)] - [String]$KMSClusterId - ) - - # Confirm the connected VIServer is vCenter - ConfirmIsVCenter - - # Get the cryptoManager of vCenter Server - $CM = GetCryptoManager - $ProviderId = New-Object VMware.Vim.KeyProviderId - - Write-Verbose "Generate a CryptoKey.`n" - if ($KMSClusterId) { - $ProviderId.Id = $KMSClusterId - } else { - $ProviderId = $null - } - - $KeyResult = $CM.GenerateKey($ProviderId) - if (!$keyResult.Success) { - Throw "Key generation failed, make sure the KMS Cluster exists!`n" - } - return $KeyResult -} - -Function GetCryptoManager { - <# - .SYNOPSIS - This function retrieves the cryptoManager according to the given type. - - .DESCRIPTION - This function retrieves the cryptoManager according to the given type. - - .PARAMETER Type - Specifies the type of CryptoManager instance to get, the default value is KMS. - - .EXAMPLE - C:\PS>GetCryptoManager -Type "CryptoManagerKmip" - - Retrieves the 'CryptoManagerKmip' type CryptoManager. - #> - - Param ( - [Parameter(Mandatory=$false)] - [String] $Type - ) - - Process { - $SI = Get-View Serviceinstance - $CM = Get-View $SI.Content.CryptoManager - $cryptoMgrType = $CM.GetType().Name - - if (!$Type) { - # As the type is not cared, so return the CM directly - return $CM - } - if ($cryptoMgrType -eq $Type) { - return $CM - } - - Throw "Failed to get CryptoManager instance of the required type {$Type}!" - } -} - -Function GetKeyIndex{ - <# - .SYNOPSIS - This cmdlet returns the index to the key with a matching algorithm as the KeyType parameter - - .DESCRIPTION - This cmdlet returns the index to the key with a matching algorithm as the KeyType parameter - - .PARAMETER Certs - Specifies the list of certificats. Expected format is byte[][] - - .PARAMETER KeyType - Specifies the keytype to search for - - .EXAMPLE - C:\PS>$keyIndex = GetKeyIndex $Certs RSA - C:\PS>$keyIndex = GetKeyIndex $Certs ECC - - .NOTES - Author : Chong Yeo. - Author email : cyeo@vmware.com - #> - - [CmdLetBinding()] - - param ( - [Parameter(Mandatory=$True)] - [byte[][]] $Certs, - - [Parameter(Mandatory=$True)] - [String] $KeyType - ) - process { - for ($i=0;$i -lt $Certs.Length; $i++) { - $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate - $cert.Import($Certs.Get($i)) - $certType = New-Object System.Security.Cryptography.Oid($cert.GetKeyAlgorithm()) - if ( $certType.FriendlyName -eq $keyType) { - return $i - } - } - return -1 - } -} - -Export-ModuleMember *-* -======= # Script Module : VMware.VMEncryption # Version : 1.1 @@ -4416,4 +2038,4 @@ Function GetCryptoManager { } } -Export-ModuleMember *-* \ No newline at end of file +Export-ModuleMember *-* From de8d765719d79c9e1c00acd2b3ae90f3e057a959 Mon Sep 17 00:00:00 2001 From: Chong Yeo Date: Wed, 23 May 2018 14:18:13 -0700 Subject: [PATCH 03/50] Add the following Cmdlets for vTPM Support and also change minor version from 1.1 to 1.2 Add-Vtpm Remove-Vtpm Get-VtpmCsr Set-VtpmCert Get-VtpmCert --- .../VMware.VMEncryption.psd1 | 2 +- .../VMware.VMEncryption.psm1 | 345 +++++++++++++++++- 2 files changed, 345 insertions(+), 2 deletions(-) diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 index 95b678f..aa83854 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 @@ -12,7 +12,7 @@ # RootModule = '' # Version number of this module. -ModuleVersion = '1.1' +ModuleVersion = '1.2' # ID used to uniquely identify this module GUID = 'f9592e48-6cd3-494e-891b-ee10ee9f7018' diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 index 7752274..df37e98 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 @@ -1,5 +1,5 @@ # Script Module : VMware.VMEncryption -# Version : 1.1 +# Version : 1.2 # Copyright © 2016 VMware, Inc. All Rights Reserved. @@ -1844,6 +1844,304 @@ Function Set-VMCryptoUnlock { } } +Function Add-Vtpm { + <# + .SYNOPSIS + This cmdlet adds a Virtual TPM to the specified VM. + + .DESCRIPTION + This cmdlet adds a Virtual TPM to the specified VM. + + .PARAMETER VM + Specifies the VM you want to add Virtual TPM to. + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Add-Vtpm $vm1 + + Encrypts $vm1's VM home and adds Virtual TPM + + .NOTES + If VM home is already encrypted, the cmdlet will add a Virtual TPM to the VM. + If VM home is not encrypted, VM home will be encrypted and Virtual TPM will be added. + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.operation = "add" + $deviceChange.device = new-object VMware.Vim.VirtualTPM + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } +} + +Function Remove-Vtpm { + <# + .SYNOPSIS + This cmdlet removes a Virtual TPM from the specified VM. + + .DESCRIPTION + This cmdlet removes a Virtual TPM from the specified VM. + + .PARAMETER VM + Specifies the VM you want to remove Virtual TPM from. + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Remove-Vtpm $vm1 + + .EXAMPLE + C:\PS>Get-VM -Name win2016 |Remove-Vtpm + + Remove Virtual TPM from VM named win2016 + + .NOTES + Removing VirtualTPM will render all encrypted data on this VM unrecoverable. + VM home encryption state will be returned to the original state before Virtual TPM is added + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding(SupportsShouldProcess=$true, ConfirmImpact = "High")] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + $message = "Removing Virtual TPM will render all encrypted data on this VM unrecoverable" + if ($PSCmdlet.ShouldProcess($message, $message + "`n Do you want to proceed", "WARNING")) { + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.operation = "remove" + $deviceChange.device = $vtpm + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } + } +} + +Function Get-VtpmCsr { + <# + .SYNOPSIS + This cmdlet gets certficate signing requests(CSR) from Virtual TPM. + + .DESCRIPTION + This cmdlet gets certficate signing requests(CSR) from Virtual TPM. + The CSR is a ComObject X509enrollment.CX509CertificateRequestPkcs10 + + .PARAMETER VM + Specifies the VM you want to get the CSRs Virtual TPM from. + + .PARAMETER KeyType [RSA | ECC] + Specify that only get CSR with public key RSA algorithm. + If none is specified, both CSR will get returned + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Get-VtpmCsr $vm1 -KeyType RSA + + .NOTES + Both RSA and ECC CSRs objects will be returned. If ECC or RSA is specified, + only the corresponding object will be returned + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM, + + [Parameter(Mandatory=$False)] + [String]$KeyType + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + # Check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contains a Virtual TPM" + return + } + + $CSRs = @() + foreach ($csrArray in $vtpm.EndorsementKeyCertificateSigningRequest) { + $csrString = [System.Convert]::ToBase64String($csrArray) + $csr = New-Object -ComObject X509enrollment.CX509CertificateRequestPkcs10 + + #decode a base64 string into a CSR object + $csr.InitializeDecode($csrString,6) + if ($keyType) { + if ($csr.PublicKey.Algorithm.FriendlyName -eq $KeyType){ + return $csr + } + } else { + $CSRs += $csr + } + } + return $CSRs + } +} + +Function Set-VtpmCert{ + <# + .SYNOPSIS + This cmdlet replaces certificates of Virtual TPM in the specified VM. + + .DESCRIPTION + This cmdlet replaces certificates to Virtual TPM in the specified VM. + + .PARAMETER VM + Specifies the VM with Virtual TPM where you want to replace the certificates to. + + .PARAMETER Cert + Specifies the certificate object (System.Security.Cryptography.X509Certificates.X509Certificate) + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>Set-VtpmCert $vm1 $certObj + + .EXAMPLE + C:\PS>Get-VM -Name win2016 | Set-VtpmCert $certObj + + Replace the appropriate certificate specified + + .NOTES + Only RSA or ECC certs will be overwritten + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM, + + [Parameter(Mandatory=$True)] + [System.Security.Cryptography.X509Certificates.X509Certificate] $Cert + ) + + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + + process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + #check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contains a Virtual TPM" + return + } + + $certOid = New-Object System.Security.Cryptography.Oid($Cert.GetKeyAlgorithm()) + + # Check which certificate to overwrite + $certLocation = GetKeyIndex $vtpm.EndorsementKeyCertificate $certOid.FriendlyName + if ($certLocation -eq -1) { + Write-Error "No Certificate with Matching Algorithm $($certOid.FriendlyName) found" + return + } + + $vtpm.EndorsementKeyCertificate[$certLocation] = $cert.GetRawCertData() + $deviceChange = New-Object VMware.Vim.VirtualDeviceConfigSpec + $deviceChange.Operation = "edit" + $deviceChange.Device = $vtpm + $VMCfgSpec = New-Object VMware.Vim.VirtualMachineConfigSpec + $VMCfgSpec.DeviceChange = $deviceChange + + return $VM.ExtensionData.ReconfigVM_task($VMCfgSpec) + } +} + +Function Get-VtpmCert{ + <# + .SYNOPSIS + This cmdlet gets certificates of Virtual TPM in the specified VM. + + .DESCRIPTION + This cmdlet gets certificates of Virtual TPM in the specified VM. + + .PARAMETER VM + Specifies the VM with Virtual TPM where you want to get the certificate from + + .EXAMPLE + C:\PS>$vm1 = Get-VM -Name win2016 + C:\PS>$certs = Get-VtpmCert $vm1 + + .NOTES + An array of certificate object (System.Security.Cryptography.X509Certificates.X509Certificate) + will be returned + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + [CmdLetBinding()] + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine] $VM + ) + Begin { + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + } + Process { + # Get vTPM from VM + $vtpm = $VM.ExtensionData.Config.Hardware.Device |Where {$_ -is [VMware.Vim.VirtualTPM]} + + # check if vTPM is already present + if (!$vtpm) { + Write-Error "$VM does not contain a Virtual TPM" + return + } + + $certs = @() + $vtpm.EndorsementKeyCertificate|foreach { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate + $cert.Import($_) + $certs += $cert + } + return $certs + } +} + Function ConfirmIsVCenter{ <# .SYNOPSIS @@ -2038,4 +2336,49 @@ Function GetCryptoManager { } } +Function GetKeyIndex{ + <# + .SYNOPSIS + This cmdlet returns the index to the key with a matching algorithm as the KeyType parameter + + .DESCRIPTION + This cmdlet returns the index to the key with a matching algorithm as the KeyType parameter + + .PARAMETER Certs + Specifies the list of certificats. Expected format is byte[][] + + .PARAMETER KeyType + Specifies the keytype to search for + + .EXAMPLE + C:\PS>$keyIndex = GetKeyIndex $Certs RSA + C:\PS>$keyIndex = GetKeyIndex $Certs ECC + + .NOTES + Author : Chong Yeo. + Author email : cyeo@vmware.com + #> + + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True)] + [byte[][]] $Certs, + + [Parameter(Mandatory=$True)] + [String] $KeyType + ) + process { + for ($i=0;$i -lt $Certs.Length; $i++) { + $cert = New-Object System.Security.Cryptography.X509Certificates.X509Certificate + $cert.Import($Certs.Get($i)) + $certType = New-Object System.Security.Cryptography.Oid($cert.GetKeyAlgorithm()) + if ( $certType.FriendlyName -eq $keyType) { + return $i + } + } + return -1 + } +} + Export-ModuleMember *-* From 3dda8cc6393c771c6e16d9a4b8845001e593fe6c Mon Sep 17 00:00:00 2001 From: lucdekens Date: Wed, 30 May 2018 19:53:01 +0200 Subject: [PATCH 04/50] VMFSIncrease - bug fix Fixed bug in New-VmfsDatastoreIncrease -Datastore -Expand -IncreaseSizeGB --- Modules/VMFSIncrease/VMFSIncrease.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/VMFSIncrease/VMFSIncrease.psm1 b/Modules/VMFSIncrease/VMFSIncrease.psm1 index ec0fa2b..90a8ccc 100644 --- a/Modules/VMFSIncrease/VMFSIncrease.psm1 +++ b/Modules/VMFSIncrease/VMFSIncrease.psm1 @@ -112,7 +112,7 @@ function Get-VmfsDatastoreIncrease 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 + DiskSizeGB = $partInfo[0].Layout.Total.BlockSize * $partInfo[0].Layout.Total.Block / 1GB DiskBlocks = $partInfo[0].Layout.Total.Block DiskBlockMB = $partInfo[0].Layout.Total.BlockSize/1MB AvailableGB = [math]::Round($partMax - $partUsed, 2) @@ -181,7 +181,7 @@ function New-VmfsDatastoreIncrease { $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 } | + $partMax = ($expOpt[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 From 2c23ecb4148670ad4994e9fda63a14888be863e9 Mon Sep 17 00:00:00 2001 From: Kyle Ruddy Date: Wed, 13 Jun 2018 14:19:58 -0400 Subject: [PATCH 05/50] Adding Script to Deploy a 1 Node SDDC for VMW on AWS Adding a new script in order to automate the deployment of a 1 node SDDC for VMware Cloud on AWS --- Scripts/VMWonAWS_1nodeDeployment.ps1 | 51 ++++++++++++++++++++++++++++ 1 file changed, 51 insertions(+) create mode 100644 Scripts/VMWonAWS_1nodeDeployment.ps1 diff --git a/Scripts/VMWonAWS_1nodeDeployment.ps1 b/Scripts/VMWonAWS_1nodeDeployment.ps1 new file mode 100644 index 0000000..8b17b16 --- /dev/null +++ b/Scripts/VMWonAWS_1nodeDeployment.ps1 @@ -0,0 +1,51 @@ +# Author: Kyle Ruddy +# Product: VMware Cloud on AWS +# Description: VMware Cloud on AWS Single Host Deployment Script using PowerCLI +# Requirements: +# - PowerShell 3.x or newer +# - PowerCLI 6.5.4 or newer + +# Set details for SDDC +$oauthToken = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" +$sddcName = "PowerCLI-1Node-SDDC" +$hostCount = "1" +$awsRegion = "US_WEST_2" + +# --- Deployment code --- +# Connect to VMware Cloud Service +Connect-Vmc -RefreshToken $oauthToken | Out-Null + +# Get ORG ID +$orgSvc = Get-VmcService -Name com.vmware.vmc.orgs +$org = $orgSvc.List() +Write-Host "Org:"$org.display_name" ID:"$org.id + +# Get Linked Account ID +$connAcctSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.connected_accounts +$connAcctId = $connAcctSvc.get($org.id) | Select-Object -ExpandProperty id +Write-Host "Account ID: $connAcctId" + +# Get Subnet ID +$compSubnetSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.compatible_subnets +$vpcMap = $compSubnetSvc.Get($org.id, $connAcctId, $region) | Select-Object -ExpandProperty vpc_map +$compSubnets = $vpcMap | Select-Object -ExpandProperty Values | Select-Object -ExpandProperty subnets +$compSubnet = $compSubnets | where {$_.name -ne $null} | Select-Object -first 1 +Write-Host "Subnet CIDR"$compSubnet.subnet_cidr_block"ID:"$compSubnet.subnet_id + +# Deploy the SDDC +$sddcSvc = Get-VmcService com.vmware.vmc.orgs.sddcs +$sddcCreateSpec = $sddcSvc.Help.create.sddc_config.Create() +$sddcCreateSpec.region = $awsRegion +$sddcCreateSpec.Name = $sddcName +$sddcCreateSpec.num_hosts = $hostCount +if ($org.properties.values.sddcTypes) {$sddcCreateSpec.sddc_type = "1NODE"} +$sddcCreateSpec.Provider = "AWS" +$accountLinkSpec = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.Create() +$accountLinkSpec.connected_account_id = $connAcctId +$custSubId0 = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.customer_subnet_ids.Element.Create() +$custSubId0 = $compSubnet.subnet_id +$accountLinkSpec.customer_subnet_ids.Add($custSubId0) | Out-Null +$sddcCreateSpec.account_link_sddc_config.Add($accountLinkSpec) | Out-Null +$sddcCreateSpec +$newSddc = $sddcSvc.create($org.Id, $sddcCreateSpec) +$newSddc \ No newline at end of file From 0a1e5a65c3a37f088da5685d9d430e6d51b07c23 Mon Sep 17 00:00:00 2001 From: Kyle Ruddy Date: Wed, 13 Jun 2018 16:04:54 -0400 Subject: [PATCH 06/50] Reorganization of VMWonAWS Script Resources Reorganizing VMWonAWS scripting resources into the appropriate folder. --- Scripts/{ => VMware_Cloud_on_AWS}/VMC Example Script.ps1 | 0 Scripts/{ => VMware_Cloud_on_AWS}/VMWonAWS_1nodeDeployment.ps1 | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename Scripts/{ => VMware_Cloud_on_AWS}/VMC Example Script.ps1 (100%) rename Scripts/{ => VMware_Cloud_on_AWS}/VMWonAWS_1nodeDeployment.ps1 (100%) diff --git a/Scripts/VMC Example Script.ps1 b/Scripts/VMware_Cloud_on_AWS/VMC Example Script.ps1 similarity index 100% rename from Scripts/VMC Example Script.ps1 rename to Scripts/VMware_Cloud_on_AWS/VMC Example Script.ps1 diff --git a/Scripts/VMWonAWS_1nodeDeployment.ps1 b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_1nodeDeployment.ps1 similarity index 100% rename from Scripts/VMWonAWS_1nodeDeployment.ps1 rename to Scripts/VMware_Cloud_on_AWS/VMWonAWS_1nodeDeployment.ps1 From b88f3a286a11eef53c2196459dc5721d82352980 Mon Sep 17 00:00:00 2001 From: Kyle Ruddy Date: Fri, 29 Jun 2018 08:38:24 -0400 Subject: [PATCH 07/50] Add VMWonAWS_InviteUsers.ps1 Script which can be used to automate the process of adding new users to a specified VMware Cloud on AWS Organization --- .../VMWonAWS_InviteUsers.ps1 | 114 ++++++++++++++++++ 1 file changed, 114 insertions(+) create mode 100644 Scripts/VMware_Cloud_on_AWS/VMWonAWS_InviteUsers.ps1 diff --git a/Scripts/VMware_Cloud_on_AWS/VMWonAWS_InviteUsers.ps1 b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_InviteUsers.ps1 new file mode 100644 index 0000000..59ddb7a --- /dev/null +++ b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_InviteUsers.ps1 @@ -0,0 +1,114 @@ +<# +.SYNOPSIS + Takes email address input in order to create VMware Cloud on AWS invites for the desired Organization +.DESCRIPTION + Script which can be used to automate the process of adding new users to a specified VMware Cloud on AWS Organization +.NOTES + Author: Kyle Ruddy, @kmruddy, kmruddy.com +.PARAMETER newUserEmail + Plain text email address or array of email addresses +.PARAMETER roleName + Desired role name of the new users, default is Organization Member +.EXAMPLE + PS > ./VMWonAWS_InviteUsers.ps1 -newUserEmail 'testuser@vmware.com' +.EXAMPLE + PS > ./VMWonAWS_InviteUsers.ps1 -newUserEmail $arrayOfEmailAddresses +#> +[CmdletBinding(SupportsShouldProcess=$True)] + param ( + + [Parameter (Mandatory = $True, Position=0)] + $newUserEmail, + [Parameter (Mandatory = $False, Position=1)] + [ValidateSet("Organization Member","Organization Owner","Support User")] + [string]$roleName = "Organization Member" + ) + + # Set Static Variables for your environment + $oauthToken = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + $orgID = 'xxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx' + + ### DO NOT MODIFY CODE BELOW THIS LINE ### + $inviteReport = @() + $userEmail = @() + + # Email Validation Testing + if ($newUserEmail -is [array]) { + foreach ($email in $newUserEmail) { + try { + $userEmail += [mailAddress]$email | select-object -ExpandProperty Address + } + catch { + Write-Warning "$email is not a valid email address" + } + } + } + else { + try { + $userEmail += [mailAddress]$newUserEmail | select-object -ExpandProperty Address + } + catch { + Write-Warning "$newUserEmail is not a valid email address" + } + } + + if ($userEmail.Count -eq 0) { + Write-Warning "No valid email addresses found." + Break + } + + # Validation and translation of the role name to the role ID + if ($roleName -eq 'Organization Member') { + $orgRoleNames = @("org_member") + } + elseif ($roleName -eq 'Organization Owner') { + $orgRoleNames = @("org_owner") + } + elseif ($roleName -eq 'Support User') { + $orgRoleNames = @("support_user") + } + + # Creating custom objects to start building out the body input + $bodyObj = new-object -TypeName System.Object + $SvcRoleNames = @("vmc-user:full") + $SvcDefinitionLink = '/csp/gateway/slc/api/definitions/external/ybUdoTC05kYFC9ZG560kpsn0I8M_' + $bodyObj | Add-Member -Name 'orgRoleNames' -MemberType Noteproperty -Value $orgRoleNames + $serviceRolesDtos = New-Object -TypeName System.Object + $serviceRolesDtos | Add-Member -Name 'serviceDefinitionLink' -MemberType Noteproperty -Value $SvcDefinitionLink + $serviceRolesDtos | Add-Member -Name 'serviceRoleNames' -MemberType Noteproperty -Value $SvcRoleNames + $bodyObj | Add-Member -Name 'serviceRolesDtos' -MemberType Noteproperty -Value @($serviceRolesDtos) + $bodyObj | Add-Member -Name 'usernames' -MemberType Noteproperty -Value $userEmail + $body = $bodyObj | ConvertTo-Json -Depth 100 + + # Connecting to the REST API service for authentication and then to perform the POST method + $connection = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize?refresh_token=$oauthToken" -Method Post + $accesskey = ($connection.content | Convertfrom-json).access_token + $inviteUsers = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/orgs/$orgID/invitations" -headers @{"csp-auth-token"="$accesskey"} -Method Post -Body $body -ContentType "application/json" + + # Outputting the successful invite which was just created + $orgInviteRefResponse = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/orgs/$orgid/invitations" -headers @{"csp-auth-token"="$accessKey"} -Method Get + if ($orgInviteRefResponse) { + $orgInviteRefObject = $orgInviteRefResponse | ConvertFrom-Json + + foreach ($inviteRef in $orgInviteRefObject) { + $link = $inviteRef.refLink + $orgInviteResponse = Invoke-WebRequest -Uri "https://console.cloud.vmware.com$link" -headers @{"csp-auth-token"="$accessKey"} -Method Get + + $orgInviteObject = $orgInviteResponse.content | ConvertFrom-Json + + foreach ($emailInput in $userEmail) { + + if ($orgInviteObject.username -eq $emailInput) { + $i = New-Object System.Object + $i | Add-Member -Type NoteProperty -Name InviteID -Value $orgInviteObject.refLink.Substring($orgInviteObject.refLink.Length - 36) + $i | Add-Member -Type NoteProperty -Name Username -Value $orgInviteObject.username + $i | Add-Member -Type NoteProperty -Name Status -Value $orgInviteObject.status + $i | Add-Member -Type NoteProperty -Name OrgRoles -Value ($orgInviteObject.OrgRoleNames -join ", ") + $i | Add-Member -Type NoteProperty -Name Requester -Value $orgInviteObject.generatedBy + $inviteReport += $i + } + } + } + } + + return $inviteReport \ No newline at end of file From e36208e2db0b3a3b369c9638a9c326169d99f6e6 Mon Sep 17 00:00:00 2001 From: simonfangyingzhang Date: Tue, 3 Jul 2018 03:25:29 +0100 Subject: [PATCH 08/50] Update VMware.VMEncryption.psd1 VMware.VimAutomation.Core 10.1.0.8344055 instead of VMware.VimAutomation.Core 10.1.0.8346946 --- Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 index aa83854..8a93a97 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 @@ -49,7 +49,7 @@ Copyright = 'Copyright (c) 2016 VMware, Inc. All rights reserved.' # Modules that must be imported into the global environment prior to importing this module RequiredModules = @( -@{"ModuleName"="VMware.VimAutomation.Core";"ModuleVersion"="10.1.0.8346946"} +@{"ModuleName"="VMware.VimAutomation.Core";"ModuleVersion"="10.1.0.8344055"} ) # Assemblies that must be loaded prior to importing this module From d9768c21aca70153e9d5e547a48739f7d212a640 Mon Sep 17 00:00:00 2001 From: William Lam Date: Tue, 17 Jul 2018 05:21:32 -0700 Subject: [PATCH 09/50] VMTX Template support for VMC-based Content Library --- Modules/ContentLibrary/ContentLibrary.psm1 | 190 +++++++++++++++++---- 1 file changed, 154 insertions(+), 36 deletions(-) diff --git a/Modules/ContentLibrary/ContentLibrary.psm1 b/Modules/ContentLibrary/ContentLibrary.psm1 index e2fef41..318b999 100644 --- a/Modules/ContentLibrary/ContentLibrary.psm1 +++ b/Modules/ContentLibrary/ContentLibrary.psm1 @@ -2,10 +2,10 @@ <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function lists all available vSphere Content Libaries @@ -87,10 +87,10 @@ Function Get-ContentLibraryItems { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function lists all items within a given vSphere Content Library @@ -158,10 +158,10 @@ Function Get-ContentLibraryItemFiles { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function lists all item files within a given vSphere Content Library @@ -225,10 +225,10 @@ Function Set-ContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function updates the JSON Persistence property for a given Content Library @@ -281,10 +281,10 @@ Function New-ExtReplicatedContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function creates a new Subscriber Content Library from a JSON Persisted @@ -345,10 +345,10 @@ Function Remove-SubscribedContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function deletes a Subscriber Content Library @@ -387,10 +387,10 @@ Function New-LocalContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function creates a new Subscriber Content Library from a JSON Persisted @@ -444,10 +444,10 @@ Function Remove-LocalContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function deletes a Local Content Library @@ -486,10 +486,10 @@ Function Copy-ContentLibrary { <# .NOTES =========================================================================== - Created by: William Lam - Organization: VMware - Blog: www.virtuallyghetto.com - Twitter: @lamw + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw =========================================================================== .DESCRIPTION This function copies all library items from one Content Library to another @@ -578,4 +578,122 @@ Function Copy-ContentLibrary { } } } +} + +Function New-VMTX { +<# + .NOTES + =========================================================================== + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + .DESCRIPTION + This function clones a VM to VM Template in Content Library (currently only supported on VMC) + .PARAMETER SourceVMName + The name of the source VM to clone + .PARAMETER VMTXName + The name of the VM Template in Content Library + .PARAMETER Description + Description of the VM template + .PARAMETER LibaryName + The name of the Content Library to clone to + .PARAMETER FolderName + The name of vSphere Folder (Defaults to Workloads for VMC) + .PARAMETER ResourcePoolName + The name of the vSphere Resource Pool (Defaults to Compute-ResourcePools for VMC) + .EXAMPLE + New-VMTX -SourceVMName "Windows10-BaseInstall" -VMTXName "Windows10-VMTX-Template" -LibraryName "VMC-CL-01" +#> + param( + [Parameter(Mandatory=$true)][String]$SourceVMName, + [Parameter(Mandatory=$true)][String]$VMTXName, + [Parameter(Mandatory=$false)][String]$Description, + [Parameter(Mandatory=$true)][String]$LibraryName, + [Parameter(Mandatory=$false)][String]$FolderName="Workloads", + [Parameter(Mandatory=$false)][String]$ResourcePoolName="Compute-ResourcePool" + ) + + $vmtxService = Get-CisService -Name "com.vmware.vcenter.vm_template.library_items" + + $sourceVMId = ((Get-VM -Name $SourceVMName).ExtensionData.MoRef).Value + $libraryId = ((Get-ContentLibrary -LibraryName $LibraryName).Id).Value + $folderId = ((Get-Folder -Name $FolderName).ExtensionData.MoRef).Value + $rpId = ((Get-ResourcePool -Name $ResourcePoolName).ExtensionData.MoRef).Value + + $vmtxCreateSpec = $vmtxService.Help.create.spec.Create() + $vmtxCreateSpec.source_vm = $sourceVMId + $vmtxCreateSpec.name = $VMTXName + $vmtxCreateSpec.description = $Description + $vmtxCreateSpec.library = $libraryId + $vmtxCreateSpec.placement.folder = $folderId + $vmtxCreateSpec.placement.resource_pool = $rpId + + Write-Host "`nCreating new VMTX Template from $SourceVMName in Content Library $LibraryName ..." + $result = $vmtxService.create($vmtxCreateSpec) +} + +Function New-VMFromVMTX { +<# + .NOTES + =========================================================================== + Created by: William Lam + Organization: VMware + Blog: www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + .DESCRIPTION + This function deploys a new VM from Template in Content Library (currently only supported in VMC) + .PARAMETER VMTXName + The name of the VM Template in Content Library to deploy from + .PARAMETER NewVMName + The name of the new VM to deploy + .PARAMETER FolderName + The name of vSphere Folder (Defaults to Workloads for VMC) + .PARAMETER ResourcePoolName + The name of the vSphere Resource Pool (Defaults to Compute-ResourcePools for VMC) + .PARAMETER NumCpu + The number of vCPU to configure for the new VM + .PARAMETER MemoryMb + The amount of memory (MB) to configure for the new VM + .PARAMETER PowerOn + To power on the VM after deploy + .EXAMPLE + New-VMFromVMTX -NewVMName "FooFoo" -VMTXName "FooBar" -PowerOn $true -NumCpu 4 -MemoryMB 2048 +#> + param( + [Parameter(Mandatory=$true)][String]$VMTXName, + [Parameter(Mandatory=$true)][String]$NewVMName, + [Parameter(Mandatory=$false)][String]$FolderName="Workloads", + [Parameter(Mandatory=$false)][String]$ResourcePoolName="Compute-ResourcePool", + [Parameter(Mandatory=$false)][String]$DatastoreName="WorkloadDatastore", + [Parameter(Mandatory=$false)][Int]$NumCpu, + [Parameter(Mandatory=$false)][Int]$MemoryMB, + [Parameter(Mandatory=$false)][Boolean]$PowerOn=$false + ) + + $vmtxService = Get-CisService -Name "com.vmware.vcenter.vm_template.library_items" + $vmtxId = (Get-ContentLibraryItem -Name $VMTXName).Id + $folderId = ((Get-Folder -Name $FolderName).ExtensionData.MoRef).Value + $rpId = ((Get-ResourcePool -Name $ResourcePoolName).ExtensionData.MoRef).Value + $datastoreId = ((Get-Datastore -Name $DatastoreName).ExtensionData.MoRef).Value + + $vmtxDeploySpec = $vmtxService.Help.deploy.spec.Create() + $vmtxDeploySpec.name = $NewVMName + $vmtxDeploySpec.powered_on = $PowerOn + $vmtxDeploySpec.placement.folder = $folderId + $vmtxDeploySpec.placement.resource_pool = $rpId + $vmtxDeploySpec.vm_home_storage.datastore = $datastoreId + $vmtxDeploySpec.disk_storage.datastore = $datastoreId + + if($NumCpu) { + $vmtxDeploySpec.hardware_customization.cpu_update.num_cpus = $NumCpu + } + if($MemoryMB) { + $vmtxDeploySpec.hardware_customization.memory_update.memory = $MemoryMB + } + + Write-Host "`nDeploying new VM $NewVMName from VMTX Template $VMTXName ..." + $results = $vmtxService.deploy($vmtxId,$vmtxDeploySpec) } \ No newline at end of file From ad76a77c2088fd9201e2e2ee2f424cd9746caf5d Mon Sep 17 00:00:00 2001 From: William Lam Date: Mon, 23 Jul 2018 13:23:39 -0700 Subject: [PATCH 10/50] PowerShell module for VMware Cloud Services Portal API --- Modules/VMware.CSP/VMware.CSP.psm1 | 54 ++++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 Modules/VMware.CSP/VMware.CSP.psm1 diff --git a/Modules/VMware.CSP/VMware.CSP.psm1 b/Modules/VMware.CSP/VMware.CSP.psm1 new file mode 100644 index 0000000..b4b4515 --- /dev/null +++ b/Modules/VMware.CSP/VMware.CSP.psm1 @@ -0,0 +1,54 @@ +Function Get-CSPAccessToken { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 07/23/2018 + Organization: VMware + Blog: https://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .DESCRIPTION + Converts a Refresh Token from the VMware Console Services Portal + to CSP Access Token to access CSP API + .PARAMETER RefreshToken + The Refresh Token from the VMware Console Services Portal + .EXAMPLE + Get-CSPAccessToken -RefreshToken $RefreshToken + #> + Param ( + [Parameter(Mandatory=$true)][String]$RefreshToken + ) + + $results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize?refresh_token=$RefreshToken" -Method POST -ContentType "application/json" -UseBasicParsing -Headers @{"csp-auth-token"="$RefreshToken"} + if($results.StatusCode -ne 200) { + Write-Host -ForegroundColor Red "Failed to retrieve Access Token, please ensure your VMC Refresh Token is valid and try again" + break + } + $accessToken = ($results | ConvertFrom-Json).access_token + Write-Host "CSP Auth Token has been successfully retrieved and saved to `$env:cspAuthToken" + $env:cspAuthToken = $accessToken +} + +Function Get-CSPServices { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 07/23/2018 + Organization: VMware + Blog: https://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .DESCRIPTION + Returns the list of CSP Services avialable for given user + .EXAMPLE + Get-CSPServices + #> + If (-Not $env:cspAuthToken) { Write-error "CSP Auth Token not found, please run Get-CSPAccessToken" } Else { + $results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/slc/api/definitions?expand=1" -Method GET -ContentType "application/json" -UseBasicParsing -Headers @{"csp-auth-token"="$env:cspAuthToken"} + ((($results.Content) | ConvertFrom-Json).results | where {$_.visible -eq $true}).displayName + } +} \ No newline at end of file From 50b76efef612424a73bdedd583ca13ad35c6ab03 Mon Sep 17 00:00:00 2001 From: dmilov Date: Tue, 14 Aug 2018 17:03:12 +0300 Subject: [PATCH 11/50] Functions for reading a VM's vmsd file content and search for specific settings To be able to identify certain VM has linked clone children a specific setting has to be read from the VM's snapshot config file. For the purpose of this I created two functions that enable reading full content of the vmsd file as well as searching for a specific setting in the vmsd file content. --- Scripts/ReadVMSnapshotConfig.ps1 | 104 +++++++++++++++++++++++++++++++ 1 file changed, 104 insertions(+) create mode 100644 Scripts/ReadVMSnapshotConfig.ps1 diff --git a/Scripts/ReadVMSnapshotConfig.ps1 b/Scripts/ReadVMSnapshotConfig.ps1 new file mode 100644 index 0000000..fe274ee --- /dev/null +++ b/Scripts/ReadVMSnapshotConfig.ps1 @@ -0,0 +1,104 @@ +function Get-VMSnapshotConfigContent { +<# + .SYNOPSIS + Reads .vmsd file content + + .DESCRIPTION + Build the vmsd file http URI following https://code.vmware.com/apis/358/vsphere#/doc/vim.FileManager.html + and reads its content with the session established by Connect-VIServer + + .INPUTS + VirtualMachine + + .OUTPUTS + String - the content of the vmsd file + + .NOTES + Author: Dimitar Milov + Version: 1.0 + + .EXAMPLE + Get-VM | Get-VMSnapshotConfigContent +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory=$true, ValueFromPipeline=$true)] + [ValidateNotNull()] + [VMware.VimAutomation.Types.VirtualMachine] + $VM +) + +PROCESS { + # Create web client from current session + $sessionKey = $vm.GetClient().ConnectivityService.CurrentUserSession.SoapSessionKey + $certValidationHandler = $vm.GetClient().ConnectivityService.GetValidationHandlerForCurrentServer() + $webClient = [vmware.vimautomation.common.util10.httpclientUtil]::CreateHttpClientWithSessionReuse($certValidationHandler, $sessionKey, $null) + + # Build VMSD file http URI + # https://code.vmware.com/apis/358/vsphere#/doc/vim.FileManager.html + $vmName = $vm.Name + $datastoreName = ($vm | Get-Datastore).Name + $dcName = ($vm | Get-Datacenter).Name + $serverAddress = $vm.GetClient().ConnectivityService.ServerAddress + $vmsdUri = [uri]"https://$serverAddress/folder/$vmName/$vmName.vmsd?dcPath=$dcName&dsName=$datastoreName" + + # Get VMSD content as string + $task = $webClient.GetAsync($vmsdUri) + $task.Wait() + $vmsdContent = $task.Result.Content.ReadAsStringAsync().Result + + # Dispose web client + $webClient.Dispose() + + # Result + $vmsdContent +} + +} + +function Get-VMSnapshotConfigSetting { +<# + .SYNOPSIS + Gets the value of a specified key from the snapshot config file content + + .DESCRIPTION + Reads the VM's snapshot config file and searches for specified key. + If key is found its value is returned as an output + + .INPUTS + VirtualMachine and key + + .OUTPUTS + String - config value for the specified key + + .NOTES + Author: Dimitar Milov + Version: 1.0 + + .EXAMPLE + Get-VM | Get-VMSnapshotConfigSetting -Key "numSentinels" +#> +[CmdletBinding()] +param( + [Parameter(Mandatory=$true, ValueFromPipeline=$true)] + [ValidateNotNull()] + [VMware.VimAutomation.Types.VirtualMachine] + $VM, + + [Parameter(Mandatory=$true)] + [ValidateNotNull()] + [string] + $Key +) + +PROCESS { + $content = Get-VMSnapshotConfigContent -vm $vm + + $keyMatch = $content | Select-String ('{0} = "(?.*)"' -f $key) + + if ($keyMatch.Matches -ne $null) { + $keyMatch.Matches[0].Groups["value"].Value + } +} +} From 61a9929bcaa37534f85b1655443ff7d96a1869b5 Mon Sep 17 00:00:00 2001 From: AndyG Date: Mon, 20 Aug 2018 15:52:41 -0400 Subject: [PATCH 12/50] Added Get-NSXTTransportNodes Added Get-NSXTTransportNodes --- Modules/NSXT/NSXT.psm1 | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index f8dcb49..a6afe2d 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -256,5 +256,41 @@ Function Get-NSXTManager { $results+=$tmp } } + $results +} + +Function Get-NSXTTransportNodes { + Param ( + [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id + ) + + $transport_nodesService = Get-NsxtService -Name "com.vmware.nsx.transport_nodes" + $transport_nodesstateService = Get-NsxtService -Name "com.vmware.nsx.transport_nodes.state" + + if($Id) { + $transport_nodes = $transport_nodesService.get($Id) + } else { + $transport_nodes = $transport_nodesService.list().results + } + + $results = @() + foreach ($transport_node in $transport_nodes) { + + $transport_nodesstate = $transport_nodesstateService.get("$($transport_node.Id)") + + $tmp = [pscustomobject] @{ + Id = $transport_node.Id; + Name = $transport_node.display_name; + Tags = $transport_node.tags; + MaintenanceMode = $transport_node.maintenance_mode; + HostSwitchesName = $transport_node.host_switches.host_switch_name; + Default_gateway = $transport_nodesstate.host_switch_states.endpointsdefault_gateway; + Device_name = $transport_nodesstate.host_switch_states.endpoints.device_name; + Ip = $transport_nodesstate.host_switch_states.endpoints.ip; + Subnet_mask =$transport_nodesstate.host_switch_states.endpoints.subnet_mask + } + $results+=$tmp + } + $results } \ No newline at end of file From 8ae75925af03fac46552e572d9af40b69fab5391 Mon Sep 17 00:00:00 2001 From: Kyle Ruddy Date: Tue, 21 Aug 2018 15:40:01 -0400 Subject: [PATCH 13/50] Update 1 Host Script Updating the script to not require the association of an AWS Account, plus some other general corrections. --- .../VMWonAWS_1nodeDeployment.ps1 | 55 ++++++++++++------- 1 file changed, 35 insertions(+), 20 deletions(-) diff --git a/Scripts/VMware_Cloud_on_AWS/VMWonAWS_1nodeDeployment.ps1 b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_1nodeDeployment.ps1 index 8b17b16..2a41690 100644 --- a/Scripts/VMware_Cloud_on_AWS/VMWonAWS_1nodeDeployment.ps1 +++ b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_1nodeDeployment.ps1 @@ -7,9 +7,10 @@ # Set details for SDDC $oauthToken = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" -$sddcName = "PowerCLI-1Node-SDDC" +$sddcName = "PowerCLI-1Host-SDDC" $hostCount = "1" $awsRegion = "US_WEST_2" +$useAwsAccount = $false # --- Deployment code --- # Connect to VMware Cloud Service @@ -18,19 +19,25 @@ Connect-Vmc -RefreshToken $oauthToken | Out-Null # Get ORG ID $orgSvc = Get-VmcService -Name com.vmware.vmc.orgs $org = $orgSvc.List() -Write-Host "Org:"$org.display_name" ID:"$org.id +Write-Output -InputObject "Org: $($org.display_name) ID: $($org.id)" -# Get Linked Account ID -$connAcctSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.connected_accounts -$connAcctId = $connAcctSvc.get($org.id) | Select-Object -ExpandProperty id -Write-Host "Account ID: $connAcctId" +# Check to use the already existing AWS account connection +if ($useAwsAccount -eq $true) { + # Get Linked Account ID + $connAcctSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.connected_accounts + $connAcctId = $connAcctSvc.get($org.id) | Select-Object -ExpandProperty id + Write-Output -InputObject "Account ID: $connAcctId" -# Get Subnet ID -$compSubnetSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.compatible_subnets -$vpcMap = $compSubnetSvc.Get($org.id, $connAcctId, $region) | Select-Object -ExpandProperty vpc_map -$compSubnets = $vpcMap | Select-Object -ExpandProperty Values | Select-Object -ExpandProperty subnets -$compSubnet = $compSubnets | where {$_.name -ne $null} | Select-Object -first 1 -Write-Host "Subnet CIDR"$compSubnet.subnet_cidr_block"ID:"$compSubnet.subnet_id + # Get Subnet ID + $compSubnetSvc = Get-VmcService -Name com.vmware.vmc.orgs.account_link.compatible_subnets + $vpcMap = $compSubnetSvc.Get($org.id, $connAcctId, $region) | Select-Object -ExpandProperty vpc_map + $compSubnets = $vpcMap | Select-Object -ExpandProperty Values | Select-Object -ExpandProperty subnets + $compSubnet = $compSubnets | where {$_.name -ne $null} | Select-Object -first 1 + Write-Output -InputObject "Subnet CIDR $($compSubnet.subnet_cidr_block) ID: $($compSubnet.subnet_id)" +} +elseif ($useAwsAccount -eq $false) { + Write-Output -InputObject "AWS Account Not Configured - you must connect to an AWS account within 14 days of creating this SDDC" +} # Deploy the SDDC $sddcSvc = Get-VmcService com.vmware.vmc.orgs.sddcs @@ -40,12 +47,20 @@ $sddcCreateSpec.Name = $sddcName $sddcCreateSpec.num_hosts = $hostCount if ($org.properties.values.sddcTypes) {$sddcCreateSpec.sddc_type = "1NODE"} $sddcCreateSpec.Provider = "AWS" -$accountLinkSpec = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.Create() -$accountLinkSpec.connected_account_id = $connAcctId -$custSubId0 = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.customer_subnet_ids.Element.Create() -$custSubId0 = $compSubnet.subnet_id -$accountLinkSpec.customer_subnet_ids.Add($custSubId0) | Out-Null -$sddcCreateSpec.account_link_sddc_config.Add($accountLinkSpec) | Out-Null -$sddcCreateSpec + +if ($useAwsAccount -eq $true) { + $accountLinkSpec = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.Create() + $accountLinkSpec.connected_account_id = $connAcctId + $custSubId0 = $sddcSvc.Help.create.sddc_config.account_link_sddc_config.Element.customer_subnet_ids.Element.Create() + $custSubId0 = $compSubnet.subnet_id + $accountLinkSpec.customer_subnet_ids.Add($custSubId0) | Out-Null + $sddcCreateSpec.account_link_sddc_config.Add($accountLinkSpec) | Out-Null +} +elseif ($useAwsAccount -eq $false) { + $accountLinkDelaySpec = $sddcSvc.Help.create.sddc_config.account_link_config.delay_account_link.Create() + $accountLinkDelaySpec = $true + $sddcCreateSpec.account_link_config.delay_account_link = $accountLinkDelaySpec +} + $newSddc = $sddcSvc.create($org.Id, $sddcCreateSpec) -$newSddc \ No newline at end of file +$newSddc | Select-Object resource_id,status,task_type,start_time,task_id \ No newline at end of file From a332102392ced2e16d390dd34d6910a5dca91231 Mon Sep 17 00:00:00 2001 From: AndyG Date: Tue, 21 Aug 2018 16:07:17 -0400 Subject: [PATCH 14/50] Added Get-NSXTTransportNodes to FunctionsToExport Added Get-NSXTTransportNodes to FunctionsToExport --- Modules/NSXT/NSXT.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/NSXT/NSXT.psd1 b/Modules/NSXT/NSXT.psd1 index c3371b3..d9e25bc 100644 --- a/Modules/NSXT/NSXT.psd1 +++ b/Modules/NSXT/NSXT.psd1 @@ -7,7 +7,7 @@ Copyright = '(c) 2017. All rights reserved.' Description = 'Powershell Module for NSX-T REST API Functions' PowerShellVersion = '5.0' - FunctionsToExport = 'Get-NSXTComputeManager','Get-NSXTFabricNode','Get-NSXTFirewallRule','Get-NSXTIPPool','Get-NSXTLogicalSwitch','Get-NSXTManager','Get-NSXTTransportZone','Get-NSXTController' + FunctionsToExport = 'Get-NSXTComputeManager','Get-NSXTFabricNode','Get-NSXTFirewallRule','Get-NSXTIPPool','Get-NSXTLogicalSwitch','Get-NSXTManager','Get-NSXTTransportZone','Get-NSXTController','Get-NSXTTransportNodes' PrivateData = @{ PSData = @{ Tags = @('NSX-T','REST') From 3d29306cb651f54f5c5a904c2941bd090641a382 Mon Sep 17 00:00:00 2001 From: mycloudrevolution Date: Fri, 24 Aug 2018 14:20:51 +0200 Subject: [PATCH 15/50] add Module with Validate-ESXiPackages Function --- .../Validate-ESXiPackages.psm1 | 82 +++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 Modules/Validate-ESXiPackages/Validate-ESXiPackages.psm1 diff --git a/Modules/Validate-ESXiPackages/Validate-ESXiPackages.psm1 b/Modules/Validate-ESXiPackages/Validate-ESXiPackages.psm1 new file mode 100644 index 0000000..ccf5d85 --- /dev/null +++ b/Modules/Validate-ESXiPackages/Validate-ESXiPackages.psm1 @@ -0,0 +1,82 @@ +function Validate-ESXiPackages { + <# + .DESCRIPTION + Compares all ESXi Host VIBs within a vSphere with a reference Hosts. + + .NOTES + File Name : Validate-ESXiPackages.ps1 + Author : Markus Kraus + Version : 1.0 + State : Ready + + Tested Against Environment: + + vSphere Version: 6.0 U2, 6.5 U1 + PowerCLI Version: PowerCLI 10.0.0 build 7895300 + PowerShell Version: 4.0 + OS Version: Windows Server 2012 R2 + + .LINK + https://mycloudrevolution.com/ + + .EXAMPLE + Validate-ESXiPackages -Cluster (Get-Cluster) -RefernceHost (Get-VMHost | Select-Object -First 1) + + .PARAMETER Cluster + vSphere Cluster to verify + + .PARAMETER RefernceHost + The VIB Reference ESXi Host + #> + + [CmdletBinding()] + param( + [Parameter(Mandatory=$True, ValueFromPipeline=$True, HelpMessage="vSphere Cluster to verify")] + [ValidateNotNullorEmpty()] + [VMware.VimAutomation.ViCore.Impl.V1.Inventory.ComputeResourceImpl] $Cluster, + [Parameter(Mandatory=$True, ValueFromPipeline=$false, HelpMessage="The VIB Reference ESXi Host")] + [ValidateNotNullorEmpty()] + [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl] $RefernceHost + ) + + Process { + + #region: Get reference VIBs + $EsxCli2 = Get-ESXCLI -VMHost $RefernceHost -V2 + $RefernceVibList = $esxcli2.software.vib.list.invoke() + #endregion + + #region: Compare reference VIBs + $MyView = @() + foreach ($VmHost in ($Cluster | Get-VMHost)) { + + $EsxCli2 = Get-ESXCLI -VMHost $VmHost -V2 + $VibList = $esxcli2.software.vib.list.invoke() + [Array]$VibDiff = Compare-Object -ReferenceObject $RefernceVibList.ID -DifferenceObject $VibList.ID + + if($VibDiff.Count -gt 0) { + $VibDiffSideIndicator = @() + foreach ($Item in $VibDiff) { + $VibDiffSideIndicator += $($Item.SideIndicator + " " + $Item.InputObject) + } + } + else { + $VibDiffSideIndicator = $null + } + + $Report = [PSCustomObject] @{ + Host = $VmHost.Name + Version = $VmHost.Version + Build = $VmHost.Build + VibDiffCount = $VibDiff.Count + VibDiff = $VibDiff.InputObject + VibDiffSideIndicator = $VibDiffSideIndicator + } + $MyView += $Report + + } + #region: Compare reference VIBs + + $MyView + } +} \ No newline at end of file From cff2f29b9735408dd6a4ffa6e0ba0ffa5ed57948 Mon Sep 17 00:00:00 2001 From: AndyG Date: Fri, 24 Aug 2018 16:32:35 -0400 Subject: [PATCH 16/50] Added Get-TraceFlows Added Get-TraceFlows. Will add to export list if it looks good. --- Modules/NSXT/NSXT.psm1 | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index a6afe2d..8616e88 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -293,4 +293,37 @@ Function Get-NSXTTransportNodes { } $results +} + +Function Get-NSXTTraceFlows { + Param ( + [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id + ) + + $NSXTraceFlowsService = Get-NsxtService -Name "com.vmware.nsx.traceflows" + + if($Id) { + $NSXTraceFlows = $NSXTraceFlowsService.get($Id) + } else { + $NSXTraceFlows = $NSXTraceFlowsService.list().results + } + + $results = @() + foreach ($NSXTraceFlow in $NSXTraceFlows) { + + $tmp = [pscustomobject] @{ + Id = $NSXTraceFlow.Id; + Operation_State = $NSXTraceFlow.operation_state; + Delivered = $NSXTraceFlow.Counters.delivered_count; + Dropped = $NSXTraceFlow.Counters.dropped_count; + Analysis = $NSXTraceFlow.maintenance_mode; + } + $results+=$tmp + } + + $results + + if ($Id) { + write-output $Id + } } \ No newline at end of file From 3c5e8363ed71db1a850fb6d31ce06a36ca082910 Mon Sep 17 00:00:00 2001 From: AndyG Date: Fri, 24 Aug 2018 16:34:11 -0400 Subject: [PATCH 17/50] Added Get-TraceFlowsObservations Added Get-TraceFlowsObservations. Will add to export if it looks ok. --- Modules/NSXT/NSXT.psm1 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index 8616e88..bfb320f 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -326,4 +326,20 @@ Function Get-NSXTTraceFlows { if ($Id) { write-output $Id } +} + +Function Get-NSXTTraceFlowObservations { + Param ( + [parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id + ) + + $NSXTraceFlowsObservService = Get-NsxtService -Name "com.vmware.nsx.traceflows.observations" + + if($Id) { + $NSXTraceFlowsObserv = $NSXTraceFlowsObservService.list($Id) + } else { + throw "TraceFlow ID required" + } + + $NSXTraceFlowsObserv.results | select transport_node_name,component_name,@{N='PacketEvent';E={($_.resource_type).TrimStart("TraceflowObservation")}} } \ No newline at end of file From 1f6ec2c2c2188001bad863a36c0083458b42bdb6 Mon Sep 17 00:00:00 2001 From: AndyG Date: Fri, 24 Aug 2018 16:36:48 -0400 Subject: [PATCH 18/50] First try at a set- function - does not work! First try at a set- function. Does not work! Not clear how to resolve, the .create method ignores required parameters; looking for ideas. --- Modules/NSXT/NSXT.psm1 | 128 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 128 insertions(+) diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index bfb320f..b2f9c3c 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -342,4 +342,132 @@ Function Get-NSXTTraceFlowObservations { } $NSXTraceFlowsObserv.results | select transport_node_name,component_name,@{N='PacketEvent';E={($_.resource_type).TrimStart("TraceflowObservation")}} +} + +Function Set-NSXTTraceFlow { + [CmdletBinding()] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateSet("UNICAST")] + [string] + $TrafficType = "UNICAST", + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + #[ValidateScript({Get-NSXTLogicalPort -Id $_}] + [string] + $LPORTID, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$_ -match [IPAddress]$_})] + [string] + $SIPAddr, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$pattern = '^(([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2}))|(([0-9A-Fa-f]{2}[-]){5}([0-9A-Fa-f]{2}))$' + if ($_ -match ($pattern -join '|')) {$true} else { + throw "The argument '$_' does not match a valid MAC address format." + } + })] + [string] + $SMAC, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$_ -match [IPAddress]$_ })] + [string] + $DIPAddr, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$pattern = '^(([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2}))|(([0-9A-Fa-f]{2}[-]){5}([0-9A-Fa-f]{2}))$' + if ($_ -match ($pattern -join '|')) {$true} else { + throw "The argument '$_' does not match a valid MAC address format." + } + })] + [string] + $DMAC) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTraceFlowsService = Get-NsxtService -Name "com.vmware.nsx.traceflows" + + # This is where I need help - the method does not ingest the complete $traceflow_request object! + + # Create the example object + $traceflow_request = $NSXTraceFlowService.help.create.traceflow_request.Create() + $traceflow_request.lport_id = $LPORTID + $traceflow_request.timeout = '15000' + $traceflow_request.packet.routed = 'true' + $traceflow_request.packet.transport_type = $TrafficType.ToUpper() + $traceflow_request.packet.resource_type = 'FieldsPacketData' + $traceflow_request.packet.frame_size = '64' + + # The example object is missing packet data, so we create it. + $eth_header = @{src_mac = $SMAC;eth_type = '2048';dst_mac = $DMAC} + $ip_header = @{src_ip = $SIPAddr;protocol = '1';ttl = '64';dst_ip = $DIPAddr} + $traceflow_request.packet | Add-Member -NotePropertyMembers $eth_header -TypeName eth_header + $traceflow_request.packet | Add-Member -NotePropertyMembers $ip_header -TypeName ip_header + + # Alternative method of creating $traceflow_request (not working either) + <# + $TraceFlow_Request = [PSCustomObject]@{ + packet = @{routed = 'true'; + transport_type = $TrafficType.ToUpper(); + ip_header = @{src_ip = $SIPAddr;dst_ip = $DIPAddr}; + eth_header = @{dst_mac = $DMAC;src_mac = $SMAC}; + payload = 'test_payload'; + resource_type = 'FieldsPacketData'}; + timeout = '10000'; + lport_id = $LPORTID + } + #> + } + + Process + { + try + { + # This does not work, ignores eth_header,ip_header etc.. Not clear why!? + $NSXTraceFlow = $NSXTraceFlowService.create($traceflow_request) + } + + catch + { + $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. Filter by MONITORING. + } + } + + End + { + if ($NSXTraceFlow) + { + Get-NSXttraceflow + } + } } \ No newline at end of file From cca008ed276773cc93e64c6b997064e5f26937e8 Mon Sep 17 00:00:00 2001 From: Kyle Ruddy Date: Fri, 24 Aug 2018 19:49:32 -0400 Subject: [PATCH 19/50] VMWonAWS Firewall Rule Accelorator Script Addition of the script version of the VMware Cloud on AWS Firewall Rule Accelorator functionality --- .../VMWonAWS_FirewallRuleAccelerator.ps1 | 209 ++++++++++++++++++ 1 file changed, 209 insertions(+) create mode 100644 Scripts/VMware_Cloud_on_AWS/VMWonAWS_FirewallRuleAccelerator.ps1 diff --git a/Scripts/VMware_Cloud_on_AWS/VMWonAWS_FirewallRuleAccelerator.ps1 b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_FirewallRuleAccelerator.ps1 new file mode 100644 index 0000000..de5b870 --- /dev/null +++ b/Scripts/VMware_Cloud_on_AWS/VMWonAWS_FirewallRuleAccelerator.ps1 @@ -0,0 +1,209 @@ +# Author: Kyle Ruddy +# Product: VMware Cloud on AWS +# Description: VMware Cloud on AWS Firewall Rule Accelerator for PowerCLI +# Requirements: +# - PowerShell 3.x or newer +# - PowerCLI 6.5.4 or newer +# - Use Default IP Addresses +# - Use NSX-V on VMware Cloud on AWS + +#---------- USER VARIABLES ---------------------------------------- + +$oauthToken = "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx" +$orgId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx' +$sddcId = 'xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxx' + +# ---------- DO NOT MODIFY BELOW THIS ------------------------------ + + +Connect-Vmc -RefreshToken $oauthToken | Out-Null + +$orgSvc = Get-VmcService -Name com.vmware.vmc.orgs + +if ($orgId) { + $org = $orgSvc.List() | where {$_.id -eq $orgId} +} +else {$org = $orgSvc.List()} + +if ($org -eq $null) {Write-Output "No Org Found. Exiting."; break} + +$sddcSvc = Get-VmcService -Name com.vmware.vmc.orgs.sddcs + +if ($sddcId) { + $sddc = $sddcSvc.Get($org.id, $sddcId) +} +else {$sddc = $sddcSvc.List($org.id)} + +if ($sddc -eq $null) {Write-Output "No SDDC Found. Exiting."; break} +elseif ($sddc -is [array]) {Write-Output "Multiple SDDCs Found. Please Specify an SDDC ID. Exiting."; break} + +$edgeSvc = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges +$mgwEdge = ($edgeSvc.Get($org.id,$sddcId,'gatewayServices') | Select-Object -ExpandProperty edge_page).data | where {$_.id -eq 'edge-1'} + +$ipsecSvc = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.ipsec.config +$ipsecVPN = $ipsecSvc.Get($org.id, $sddcId, $mgwEdge.id) + +$localSubnet = $ipsecVPN.sites.sites.local_subnets.subnets +$vpnSubnet = $ipsecVPN.sites.sites.peer_subnets.subnets +$vcMgmtIP = $sddc.resource_config.vc_management_ip +$vcPublicIP = $sddc.resource_config.vc_public_ip +$esxSubnet = $sddc.resource_config.esx_host_subnet +$ipsecVPNname = $ipsecVPN.sites.sites.name + +function Add-VMCFirewallRule { + <# + .NOTES + =========================================================================== + Created by: Kyle Ruddy + Date: 08/22/2018 + Organization: VMware + Blog: https://www.kmruddy.com + Twitter: @kmruddy + =========================================================================== + .SYNOPSIS + Creates a Firewall Rule for a given SDDC + .DESCRIPTION + Creates a Firewall Rule for a given SDDC + .EXAMPLE + Add-VMCFirewallRule -OrgId -sddcId -FwRuleName -SourceIpAddress -DestIpAddress -Service + + #> + param( + [Parameter(Mandatory=$true)] + [String]$OrgId, + [Parameter(Mandatory=$true)] + [String]$SddcId, + [Parameter(Mandatory=$false)] + [ValidateSet('Management Gateway','Compute Gateway')] + [String]$Edge = 'Management Gateway', + [Parameter(Mandatory=$true)] + [String]$FwRuleName, + [Parameter(Mandatory=$false)] + $SourceIpAddress, + [Parameter(Mandatory=$false)] + $DestIpAddress, + [Parameter(Mandatory=$true)] + [ValidateSet('HTTPS','ICMP','SSO','Provisioning','Any','Remote Console')] + [String]$Service, + [Parameter(Mandatory=$false)] + [ValidateSet('accept')] + $FwAction = 'accept' + + ) + + if ($edge -eq 'Management Gateway') {$EdgeId = 'edge-1'} + elseif ($edge -eq 'Compute Gateway') {$EdgeId = 'edge-2'} + else {Write-Output "No Valid Edge Input Found."} + + $fwRuleSvc = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules + + $ruleElementSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.Create() + $fwRules = $fwRuleSvc.Help.add.firewall_rules.Create() + $ruleSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Create() + + # AppSpec + $appSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.application.Create() + # ServiceSpec + $serviceSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.application.service.Element.Create() + + if ($Service -eq 'HTTPS') { + $protocol = 'TCP' + $port = @("443") + } + elseif ($Service -eq 'ICMP') { + $protocol = 'ICMP' + $icmpType = 'any' + + } + elseif ($Service -eq 'SSO') { + $protocol = 'TCP' + $port = @("7444") + } + elseif ($Service -eq 'Provisioning') { + $protocol = 'TCP' + $port = @("902") + } + elseif ($Service -eq 'Any') { + $protocol = 'Any' + $port = $null + } + elseif ($Service -eq 'Remote Console') { + $protocol = 'TCP' + $port = @("903") + } + else {Write-Output "No Protocol Found."; break} + + $serviceSpec.protocol = $protocol + + # Process ICMP Type from JSON + $icmpType = $null + if($protocol -eq 'ICMP') { + $icmpType = 'any' + } + + if ($icmpType) { + $serviceSpec.icmp_type = $icmpType} + if ($port) { + $serviceSpec.port = $port + $serviceSpec.source_port = @("any") + } + + $addSpec = $ruleElementSpec.application.service.Add($serviceSpec) + + + # Create Source Spec + if($SourceIpAddress) { + $srcSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.source.Create() + $srcSpec.exclude = $false + $srcSpec.ip_address = @($SourceIpAddress) + $ruleElementSpec.source = $srcSpec + } + + + # Create Destination Spec + if($DestIpAddress) { + $destSpec = $fwRuleSvc.Help.add.firewall_rules.firewall_rules.Element.destination.Create() + $destSpec.exclude = $false + $destSpec.ip_address = @($DestIpAddress) + $ruleElementSpec.destination = $destSpec + + } + + + $ruleElementSpec.rule_type = "user" + $ruleElementSpec.enabled = $true + $ruleElementSpec.logging_enabled = $false + + $ruleElementSpec.action = $FwAction + $ruleElementSpec.name = $FwRuleName + + # Add the individual FW rule spec into our overall firewall rules array + Write-Output "Creating VMC Firewall Rule: $FwRuleName" + $ruleSpecAdd = $ruleSpec.Add($ruleElementSpec) + + $fwRules.firewall_rules = $ruleSpec + $fwRuleAdd = $fwRuleSvc.add($orgId,$sddcId,$EdgeId,$fwRules) + +} + + +# vCenter (ANY) to VPN +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "vCenter (ANY) to $ipsecVPNname" -SourceIpAddress $vcMgmtIP -DestIpAddress $vpnSubnet -Service 'Any' + +# ESXi (ANY) to VPN +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "ESXi (ANY) to $ipsecVPNname" -SourceIpAddress $esxSubnet,'10.2.16.0/20' -DestIpAddress $vpnSubnet -Service 'Any' + +# VPN to vCenter (HTTPS) +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to vCenter (HTTPS)" -SourceIpAddress $vpnSubnet -DestIpAddress $vcMgmtIP -Service 'HTTPS' + +# VPN to vCenter (ICMP) +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to vCenter (ICMP)" -SourceIpAddress $vpnSubnet -DestIpAddress $vcMgmtIP -Service 'ICMP' + +# VPN to ESXi (Provisioning) +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to ESXi (Provisioning)" -SourceIpAddress $vpnSubnet -DestIpAddress $esxSubnet,'10.2.16.0/20' -Service 'Provisioning' + +# VPN to ESXi (Remove Console) +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to ESXi (Remote Console)" -SourceIpAddress $vpnSubnet -DestIpAddress $esxSubnet,'10.2.16.0/20' -Service 'Remote Console' + +# VPN to ESXi (ICMP) +Add-VMCFirewallRule -OrgId $org.Id -sddcId $sddc.id -FwRuleName "$ipsecVPNname to ESXi (ICMP)" -SourceIpAddress $vpnSubnet -DestIpAddress $esxSubnet,'10.2.16.0/20' -Service 'ICMP' \ No newline at end of file From 127252196f417553ba09e05b7bb980f4f42563f0 Mon Sep 17 00:00:00 2001 From: William Lam Date: Wed, 5 Sep 2018 11:46:41 -0700 Subject: [PATCH 20/50] SDDC Summary data using GET /sddc --- Modules/VMware.VMC/VMware.VMC.psm1 | 47 +++++++++++++++++++++++++++++- 1 file changed, 46 insertions(+), 1 deletion(-) diff --git a/Modules/VMware.VMC/VMware.VMC.psm1 b/Modules/VMware.VMC/VMware.VMC.psm1 index 7b64047..982c0cc 100644 --- a/Modules/VMware.VMC/VMware.VMC.psm1 +++ b/Modules/VMware.VMC/VMware.VMC.psm1 @@ -855,4 +855,49 @@ Function New-VMCLogicalNetwork { Get-VMCLogicalNetwork -OrgName $OrgName -SDDCName $SDDCName -LogicalNetworkName $LogicalNetworkName } -Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork' \ No newline at end of file +Function Get-VMCSDDCSummary { + <# + .NOTES + =========================================================================== + Created by: VMware + Date: 09/04/18 + Organization: VMware + Blog: https://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns a number of useful informational data about a given SDDC within VMC Org + .DESCRIPTION + Returns Version, Create/Expiration Date, Deployment Type, Region, AZ, Instance Type, VPC CIDR & NSX-T + .EXAMPLE + Get-VMCSDDCSummary -Name -Org + #> + Param ( + [Parameter(Mandatory=$True)]$OrgName, + [Parameter(Mandatory=$True)]$SDDCName + ) + + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { + $orgId = (Get-VMCOrg -Name $Org).Id + $sddcId = (Get-VMCSDDC -Name $Name -Org $Org).Id + + $sddcService = Get-VmcService "com.vmware.vmc.orgs.sddcs" + $sddc = $sddcService.get($orgId,$sddcId) + + $results = [pscustomobject] @{ + Version = $sddc.resource_config.sddc_manifest.vmc_version; + CreateDate = $sddc.created; + ExpirationDate = $sddc.expiration_date; + DeploymentType = $sddc.resource_config.deployment_type; + Region = $sddc.resource_config.region; + AvailabilityZone = $sddc.resource_config.availability_zones; + InstanceType = $sddc.resource_config.sddc_manifest.esx_ami.instance_type; + VpcCIDR = $sddc.resource_config.vpc_info.vpc_cidr; + NSXT = $sddc.resource_config.nsxt; + } + $results + } +} + +Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork', 'Get-VMCSDDCSummary' \ No newline at end of file From 760c534cf74e1418d1fa61e232d6e1ecfd4c6f13 Mon Sep 17 00:00:00 2001 From: Matt Frey Date: Fri, 7 Sep 2018 11:02:42 -0500 Subject: [PATCH 21/50] Update VMware.HV.Helper.psm1 Added -DeleteFromDisk parameter to Remove-HVMachine Performed some minor cleanup (remove trailing whitespaces, capitalization) --- .../VMware.Hv.Helper/VMware.HV.Helper.psm1 | 98 +++++++++++-------- 1 file changed, 55 insertions(+), 43 deletions(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index 74bf078..58026bb 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -9988,63 +9988,75 @@ function Reset-HVMachine { $services.machine.Machine_ResetMachines($machine.id) } } -function Remove-HVMachine(){ +function Remove-HVMachine { <# .Synopsis - Remove a Horizon View desktop or desktops. - + Remove a Horizon View desktop or desktops. + .DESCRIPTION - Deletes a VM or an array of VM's from Horizon. Utilizes an Or query filter to match machine names. + Deletes a VM or an array of VM's from Horizon. Utilizes an Or query filter to match machine names. .PARAMETER HVServer - The Horizon server where the machine to be deleted resides.Parameter is not mandatory, - but if you do not specify the server, than make sure you are connected to a Horizon server + The Horizon server where the machine to be deleted resides. Parameter is not mandatory, + but if you do not specify the server, than make sure you are connected to a Horizon server first with connect-hvserver. .PARAMETER MachineNames - The name or names of the machine(s) to be deleted. Accepts a single VM or an array of VM names.This is a mandatory parameter. + The name or names of the machine(s) to be deleted. Accepts a single VM or an array of VM names.This is a mandatory parameter. + + .PARAMETER DeleteFromDisk + Determines whether the Machine VM should be deleted from vCenter Server. This is only applicable for managed machines. + This must always be true for machines in linked and instant clone desktops. + This defaults to true for linked and instant clone machines and false for all other types. .EXAMPLE - remove-HVMachine -HVServer 'horizonserver123' -MachineNames 'LAX-WIN10-002' - Deletes VM 'LAX-WIN10-002' from HV Server 'horizonserver123' + Remove-HVMachine -HVServer 'horizonserver123' -MachineNames 'LAX-WIN10-002' + Deletes VM 'LAX-WIN10-002' from HV Server 'horizonserver123' .EXAMPLE - remove-HVMachine -HVServer 'horizonserver123' -MachineNames $machines - Deletes VM's contained within an array of machine names from HV Server 'horizonserver123' - + Remove-HVMachine -HVServer 'horizonserver123' -MachineNames $machines + Deletes VM's contained within an array of machine names from HV Server 'horizonserver123' + + .EXAMPLE + Remove-HVMachine -HVServer 'horizonserver123' -MachineNames 'ManualVM01' -DeleteFromDisk:$false + Deletes VM 'ManualVM01' from Horizon inventory, but not from vSphere. Note this only works for Full Clone VMs. + .NOTES Author : Jose Rodriguez Author email : jrodsguitar@gmail.com Version : 1.0 - + ===Tested Against Environment==== Horizon View Server Version : 7.1.1 PowerCLI Version : PowerCLI 6.5, PowerCLI 6.5.1 PowerShell Version : 5.0 #> - - [CmdletBinding( + + [CmdletBinding( SupportsShouldProcess = $true, ConfirmImpact = 'High' )] - - param( - + + param( + [Parameter(Mandatory = $true)] [array] - $MachineNames, - + $MachineNames, + + [Parameter(Mandatory = $false)] + [switch]$DeleteFromDisk = $true, + [Parameter(Mandatory = $false)] $HVServer = $null - ) + ) #Connect to HV Server $services = Get-ViewAPIService -HVServer $HVServer - - if ($null -eq $services) { - Write-Error "Could not retrieve ViewApi services from connection object" + +if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" break - } + } #Connect to Query Service $queryService = New-Object 'Vmware.Hv.QueryServiceService' @@ -10096,9 +10108,9 @@ $trys = 0 foreach($session in $deleteMachine.base.session){ $sessions = $null - [VMware.Hv.SessionId[]]$sessions += $session - - } + [VMware.Hv.SessionId[]]$sessions += $session + + } try{ @@ -10110,8 +10122,8 @@ $trys = 0 #Wait more for Sessions to end - Start-Sleep -Seconds 5 - + Start-Sleep -Seconds 5 + } catch{ @@ -10121,39 +10133,39 @@ $trys = 0 write-host ($deleteMachine.base.Name -join "`n") start-sleep -seconds 5 - + } - - if(($trys -le 10)){ - + + if(($trys -le 10)){ + write-host "`n" write-host "Retrying Logoffs: $trys times" #Recheck existing sessions $deleteMachine = $machineService.Machine_GetInfos($services,$deleteThisMachine.Id) - + } - - $trys++ + + $trys++ } until((!$deleteMachine.base.session.id) -or ($trys -gt 10)) - + } #Create delete spec for the DeleteMachines method $deleteSpec = [VMware.Hv.MachineDeleteSpec]::new() -$deleteSpec.DeleteFromDisk = $true +$deleteSpec.DeleteFromDisk = $DeleteFromDisk $deleteSpec.ArchivePersistentDisk = $false - + #Delete the machines -write-host "Attempting to Delete:" +write-host "Attempting to Delete:" Write-Output ($deleteMachine.base.Name -join "`n") $bye = $machineService.Machine_DeleteMachines($services,$deleteMachine.id,$deleteSpec) [System.gc]::collect() - -} + +} function get-hvhealth { <# From a753d8251bb756aa3c523302859a95874e87d290 Mon Sep 17 00:00:00 2001 From: AndyG Date: Wed, 12 Sep 2018 13:31:03 -0400 Subject: [PATCH 22/50] Major refactoring Major refactoring - replaced hashtables with classes. Can now accept pipeline input. --- Modules/NSXT/NSXT.psm1 | 342 +++++++++++++++++++++++++++++++---------- 1 file changed, 260 insertions(+), 82 deletions(-) diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index b2f9c3c..d80a565 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -259,89 +259,114 @@ Function Get-NSXTManager { $results } -Function Get-NSXTTransportNodes { +Function Get-NSXTTransportNode { Param ( - [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id","Tranportnode_id")] + [string]$transport_node_id ) - $transport_nodesService = Get-NsxtService -Name "com.vmware.nsx.transport_nodes" - $transport_nodesstateService = Get-NsxtService -Name "com.vmware.nsx.transport_nodes.state" - - if($Id) { - $transport_nodes = $transport_nodesService.get($Id) - } else { - $transport_nodes = $transport_nodesService.list().results - } + begin + { + $NSXTransportNodesService = Get-NsxtService -Name "com.vmware.nsx.transport_nodes" - $results = @() - foreach ($transport_node in $transport_nodes) { - - $transport_nodesstate = $transport_nodesstateService.get("$($transport_node.Id)") - - $tmp = [pscustomobject] @{ - Id = $transport_node.Id; - Name = $transport_node.display_name; - Tags = $transport_node.tags; - MaintenanceMode = $transport_node.maintenance_mode; - HostSwitchesName = $transport_node.host_switches.host_switch_name; - Default_gateway = $transport_nodesstate.host_switch_states.endpointsdefault_gateway; - Device_name = $transport_nodesstate.host_switch_states.endpoints.device_name; - Ip = $transport_nodesstate.host_switch_states.endpoints.ip; - Subnet_mask =$transport_nodesstate.host_switch_states.endpoints.subnet_mask + class NSXTransportNode { + [string]$Name + [string]$Tranport_node_id + [string]$maintenance_mode + hidden $tags = [System.Collections.Generic.List[string]]::new() + hidden $host_switches = [System.Collections.Generic.List[string]]::new() + hidden [string]$host_switch_spec + hidden $transport_zone_endpoints = [System.Collections.Generic.List[string]]::new() } - $results+=$tmp } - $results + Process + { + if($transport_node_id) { + $NSXTransportNodes = $NSXTransportNodesService.get($transport_node_id) + } else { + $NSXTransportNodes = $NSXTransportNodesService.list().results + } + + foreach ($NSXTransportNode in $NSXTransportNodes) { + + $results = [NSXTransportNode]::new() + $results.Name = $NSXTransportNode.display_name; + $results.Tranport_node_id = $NSXTransportNode.Id; + $results.maintenance_mode = $NSXTransportNode.maintenance_mode; + $results.Tags = $NSXTransportNode.tags; + $results.host_switches = $NSXTransportNode.host_switches; + $results.host_switch_spec = $NSXTransportNode.host_switch_spec; + $results.transport_zone_endpoints = $NSXTransportNode.transport_zone_endpoints; + $results.host_switches = $NSXTransportNode.host_switches + write-output $results + } + } } -Function Get-NSXTTraceFlows { +Function Get-NSXTTraceFlow { Param ( - [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id + [parameter(Mandatory=$false,ValueFromPipeline=$true)] + [Alias("Id")] + [string]$traceflow_id ) $NSXTraceFlowsService = Get-NsxtService -Name "com.vmware.nsx.traceflows" - if($Id) { - $NSXTraceFlows = $NSXTraceFlowsService.get($Id) + if($traceflow_id) { + $NSXTraceFlows = $NSXTraceFlowsService.get($traceflow_id) } else { $NSXTraceFlows = $NSXTraceFlowsService.list().results } - $results = @() - foreach ($NSXTraceFlow in $NSXTraceFlows) { - - $tmp = [pscustomobject] @{ - Id = $NSXTraceFlow.Id; - Operation_State = $NSXTraceFlow.operation_state; - Delivered = $NSXTraceFlow.Counters.delivered_count; - Dropped = $NSXTraceFlow.Counters.dropped_count; - Analysis = $NSXTraceFlow.maintenance_mode; - } - $results+=$tmp + class NSXTraceFlow { + [string]$traceflow_id + hidden [string]$lport_id + [string]$Operation_State + [int]$Forwarded + [int]$Delivered + [int]$Received + [int]$Dropped + [string]$Analysis } - $results - - if ($Id) { - write-output $Id - } + foreach ($NSXTraceFlow in $NSXTraceFlows) { + + $results = [NSXTraceFlow]::new() + $results.traceflow_id = $NSXTraceFlow.Id; + $results.Operation_State = $NSXTraceFlow.operation_state; + $results.forwarded = $NSXTraceFlow.Counters.forwarded_count; + $results.delivered = $NSXTraceFlow.Counters.delivered_count; + $results.received = $NSXTraceFlow.Counters.received_count; + $results.dropped = $NSXTraceFlow.Counters.dropped_count; + $results.analysis = $NSXTraceFlow.analysis + write-output $results + } } Function Get-NSXTTraceFlowObservations { Param ( - [parameter(Mandatory=$true,ValueFromPipeline=$true)][string]$Id + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$traceflow_id ) - $NSXTraceFlowsObservService = Get-NsxtService -Name "com.vmware.nsx.traceflows.observations" - - if($Id) { - $NSXTraceFlowsObserv = $NSXTraceFlowsObservService.list($Id) - } else { - throw "TraceFlow ID required" + begin + { + $NSXTraceFlowsObservService = Get-NsxtService -Name "com.vmware.nsx.traceflows.observations" } + + Process + { + if($traceflow_id) { + $NSXTraceFlowsObserv = $NSXTraceFlowsObservService.list($traceflow_id) + } else { + throw "TraceFlow ID required" + } - $NSXTraceFlowsObserv.results | select transport_node_name,component_name,@{N='PacketEvent';E={($_.resource_type).TrimStart("TraceflowObservation")}} + $NSXTraceFlowsObserv.results | select transport_node_name,component_name,@{N='PacketEvent';E={($_.resource_type).TrimStart("TraceflowObservation")}} + } } Function Set-NSXTTraceFlow { @@ -416,36 +441,55 @@ Function Set-NSXTTraceFlow { $NSXTraceFlowsService = Get-NsxtService -Name "com.vmware.nsx.traceflows" - # This is where I need help - the method does not ingest the complete $traceflow_request object! + class ip_header { + [string]$src_ip + [string]$dst_ip + } + + class eth_header { + [string]$src_mac + [string]$dst_mac + } + + class packet_data { + [boolean]$routed + [ValidateSet("UNICAST","BROADCAST","MULTICAST","UNKNOWN")] + [string]$transport_type + [ValidateSet("BINARYPACKETDATA","FIELDSPACKETDATA")] + [string]$resource_type + [long]$frame_size + [eth_header]$eth_header = [eth_header]::new() + [ip_header]$ip_header = [ip_header]::new() - # Create the example object - $traceflow_request = $NSXTraceFlowService.help.create.traceflow_request.Create() - $traceflow_request.lport_id = $LPORTID + packet_data(){ + $this.routed = 'true' + $this.transport_type = 'UNICAST' + $this.resource_type = 'FieldsPacketData' + } + } + + class traceflow_request { + [string]$lport_id + [long]$timeout + [packet_data]$packet = [packet_data]::new() + + traceflow_request(){ + $this.timeout = '15000' + } + } + + [traceflow_request]$traceflow_request = [traceflow_request]::new() + + $traceflow_request.lport_id = '8afcd58a-4bdc-483c-97a5-c5f08df7f772' $traceflow_request.timeout = '15000' $traceflow_request.packet.routed = 'true' - $traceflow_request.packet.transport_type = $TrafficType.ToUpper() + $traceflow_request.packet.transport_type = 'UNICAST' $traceflow_request.packet.resource_type = 'FieldsPacketData' - $traceflow_request.packet.frame_size = '64' - - # The example object is missing packet data, so we create it. - $eth_header = @{src_mac = $SMAC;eth_type = '2048';dst_mac = $DMAC} - $ip_header = @{src_ip = $SIPAddr;protocol = '1';ttl = '64';dst_ip = $DIPAddr} - $traceflow_request.packet | Add-Member -NotePropertyMembers $eth_header -TypeName eth_header - $traceflow_request.packet | Add-Member -NotePropertyMembers $ip_header -TypeName ip_header - - # Alternative method of creating $traceflow_request (not working either) - <# - $TraceFlow_Request = [PSCustomObject]@{ - packet = @{routed = 'true'; - transport_type = $TrafficType.ToUpper(); - ip_header = @{src_ip = $SIPAddr;dst_ip = $DIPAddr}; - eth_header = @{dst_mac = $DMAC;src_mac = $SMAC}; - payload = 'test_payload'; - resource_type = 'FieldsPacketData'}; - timeout = '10000'; - lport_id = $LPORTID - } - #> + $traceflow_request.packet.frame_size = '128' + $traceflow_request.packet.eth_header.src_mac = '00:50:56:b3:90:e3' + $traceflow_request.packet.eth_header.dst_mac = '00:50:56:b3:0e:91' + $traceflow_request.packet.ip_header.src_ip = '15.128.160.20' + $traceflow_request.packet.ip_header.dst_ip = '15.128.160.24' } Process @@ -470,4 +514,138 @@ Function Set-NSXTTraceFlow { Get-NSXttraceflow } } -} \ No newline at end of file +} + +Function Get-NSXTEdgeCluster { + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$edge_cluster_id + ) + + Begin + { + $NSXTEdgeClustersService = Get-NsxtService -Name "com.vmware.nsx.edge_clusters" + + class NSXEdgeCluster { + [string]$Name + hidden [string]$Protection + hidden [string]$Tags + [string]$edge_cluster_id + [string]$resource_type + [string]$deployment_type + [string]$member_node_type + $members = [System.Collections.Generic.List[string]]::new() + $cluster_profile_bindings = [System.Collections.Generic.List[string]]::new() + } + } + + Process + { + if ($edge_cluster_id) { + $NSXEdgeClusters = $NSXTEdgeClustersService.get($edge_cluster_id) + } + else { + $NSXEdgeClusters = $NSXTEdgeClustersService.list().results + } + + foreach ($NSXEdgeCluster in $NSXEdgeClusters) { + + $results = [NSXEdgeCluster]::new() + $results.Name = $NSXEdgeCluster.display_name; + $results.Protection = $NSXEdgeCluster.Protection; + $results.edge_cluster_id = $NSXEdgeCluster.Id; + $results.resource_type = $NSXEdgeCluster.resource_type; + $results.Tags = $NSXEdgeCluster.tags; + $results.deployment_type = $NSXEdgeCluster.deployment_type; + $results.member_node_type = $NSXEdgeCluster.member_node_type; + $results.members = $NSXEdgeCluster.members; + $results.cluster_profile_bindings = $NSXEdgeCluster.cluster_profile_bindings + write-output $results + } + } +} + +Function Get-NSXTLogicalRouter { + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$Logical_router_id + ) + + begin + { + $NSXTLogicalRoutersService = Get-NsxtService -Name "com.vmware.nsx.logical_routers" + + class NSXTLogicalRouter { + [string]$Name + [string]$Logical_router_id + hidden [string]$Tags + [string]$edge_cluster_id + [ValidateSet("TIER0","TIER1")] + [string]$router_type + [ValidateSet("ACTIVE_ACTIVE","ACTIVE_STANDBY","")] + [string]$high_availability_mode + [ValidateSet("PREEMPTIVE","NON_PREEMPTIVE","")] + [string]$failover_mode + [string]$external_transit + [string]$internal_transit + } + } + + Process + { + if($Logical_router_id) { + $NSXLogicalRouters = $NSXTLogicalRoutersService.get($Logical_router_id) + } else { + $NSXLogicalRouters = $NSXTLogicalRoutersService.list().results + } + + foreach ($NSXLogicalRouter in $NSXLogicalRouters) { + + $results = [NSXTLogicalRouter]::new() + $results.Name = $NSXLogicalRouter.display_name; + $results.Logical_router_id = $NSXLogicalRouter.Id; + $results.Tags = $NSXLogicalRouter.tags; + $results.edge_cluster_id = $NSXLogicalRouter.edge_cluster_id; + $results.router_type = $NSXLogicalRouter.router_type; + $results.high_availability_mode = $NSXLogicalRouter.high_availability_mode; + $results.failover_mode =$NSXLogicalRouter.failover_mode; + $results.external_transit = $NSXLogicalRouter.advanced_config.external_transit_networks; + $results.internal_transit = $NSXLogicalRouter.advanced_config.internal_transit_network + write-output $results + } + } +} + +Function Get-NSXTRoutingTable { + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [string]$Logical_router_id, + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [string]$Tranport_node_id + ) + + Begin + { + $NSXTRoutingTableService = Get-NsxtService -Name "com.vmware.nsx.logical_routers.routing.route_table" + + class NSXTRoutingTable { + [string]$Name + hidden [string]$Id + hidden $tags = [System.Collections.Generic.List[string]]::new() + #more things need to be added when .list actually works + } + } + + Process + { + $NSXTRoutingTable = [NSXTRoutingTable]::new() + + $NSXTRoutingTable = $NSXTRoutingTableService.list($Logical_router_id, $transport_node_id) + + #$NSXTRoutingTable = $NSXTRoutingTableService.list("ca02cb69-0210-4f34-8164-42943a1cc974","309fda89-3439-40ff-996e-b7eb2ec69ace") + + write-output $NSXTRoutingTable + } +} From 75a2562d974f96625c0d4aff7a8be43849362fb6 Mon Sep 17 00:00:00 2001 From: AndyG Date: Wed, 12 Sep 2018 13:45:38 -0400 Subject: [PATCH 23/50] Updates to Set-NSXTraceFlow Updates to Set-NSXTraceFlow. Added more comment and aligned variable names with api --- Modules/NSXT/NSXT.psm1 | 40 ++++++++++++++++++---------------------- 1 file changed, 18 insertions(+), 22 deletions(-) diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index d80a565..c68b135 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -378,21 +378,21 @@ Function Set-NSXTTraceFlow { ParameterSetName='Parameter Set VM Type')] [ValidateSet("UNICAST")] [string] - $TrafficType = "UNICAST", + $transport_type = "UNICAST", [parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName='Parameter Set VM Type')] [ValidateNotNullOrEmpty()] #[ValidateScript({Get-NSXTLogicalPort -Id $_}] [string] - $LPORTID, + $lport_id, [parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName='Parameter Set VM Type')] [ValidateNotNullOrEmpty()] [ValidateScript({$_ -match [IPAddress]$_})] [string] - $SIPAddr, + $src_ip, [parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName='Parameter Set VM Type')] @@ -403,14 +403,14 @@ Function Set-NSXTTraceFlow { } })] [string] - $SMAC, + $src_mac, [parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName='Parameter Set VM Type')] [ValidateNotNullOrEmpty()] [ValidateScript({$_ -match [IPAddress]$_ })] [string] - $DIPAddr, + $dst_ip, [parameter(Mandatory=$true, ValueFromPipeline=$true, ParameterSetName='Parameter Set VM Type')] @@ -421,7 +421,7 @@ Function Set-NSXTTraceFlow { } })] [string] - $DMAC) + $dst_mac) Begin { @@ -477,26 +477,22 @@ Function Set-NSXTTraceFlow { $this.timeout = '15000' } } - - [traceflow_request]$traceflow_request = [traceflow_request]::new() - - $traceflow_request.lport_id = '8afcd58a-4bdc-483c-97a5-c5f08df7f772' - $traceflow_request.timeout = '15000' - $traceflow_request.packet.routed = 'true' - $traceflow_request.packet.transport_type = 'UNICAST' - $traceflow_request.packet.resource_type = 'FieldsPacketData' - $traceflow_request.packet.frame_size = '128' - $traceflow_request.packet.eth_header.src_mac = '00:50:56:b3:90:e3' - $traceflow_request.packet.eth_header.dst_mac = '00:50:56:b3:0e:91' - $traceflow_request.packet.ip_header.src_ip = '15.128.160.20' - $traceflow_request.packet.ip_header.dst_ip = '15.128.160.24' } Process { + [traceflow_request]$traceflow_request = [traceflow_request]::new() + + $traceflow_request.lport_id = $lport_id + $traceflow_request.packet.transport_type = $transport_type + $traceflow_request.packet.eth_header.src_mac = $src_mac + $traceflow_request.packet.eth_header.dst_mac = $dst_mac + $traceflow_request.packet.ip_header.src_ip = $src_ip + $traceflow_request.packet.ip_header.dst_ip = $dst_ip + try { - # This does not work, ignores eth_header,ip_header etc.. Not clear why!? + # This does not work, bug report submitted to PowerCLI team $NSXTraceFlow = $NSXTraceFlowService.create($traceflow_request) } @@ -509,6 +505,7 @@ Function Set-NSXTTraceFlow { End { + # Likely don't need this and will replace with write-output $NSXTraceFlow but I can't test right now due to bug if ($NSXTraceFlow) { Get-NSXttraceflow @@ -642,10 +639,9 @@ Function Get-NSXTRoutingTable { { $NSXTRoutingTable = [NSXTRoutingTable]::new() + # this does not work, bug report submitted to PowerCLI team $NSXTRoutingTable = $NSXTRoutingTableService.list($Logical_router_id, $transport_node_id) - #$NSXTRoutingTable = $NSXTRoutingTableService.list("ca02cb69-0210-4f34-8164-42943a1cc974","309fda89-3439-40ff-996e-b7eb2ec69ace") - write-output $NSXTRoutingTable } } From 33bb7f6b3a9d05d94dbd39ca5795eb1f5b4ace2c Mon Sep 17 00:00:00 2001 From: William Lam Date: Wed, 12 Sep 2018 11:38:49 -0700 Subject: [PATCH 24/50] Added {Get,New,Remove}-VMCPublicIP function --- Modules/VMware.VMC/VMware.VMC.psm1 | 110 ++++++++++++++++++++++++++++- 1 file changed, 109 insertions(+), 1 deletion(-) diff --git a/Modules/VMware.VMC/VMware.VMC.psm1 b/Modules/VMware.VMC/VMware.VMC.psm1 index 982c0cc..919bea2 100644 --- a/Modules/VMware.VMC/VMware.VMC.psm1 +++ b/Modules/VMware.VMC/VMware.VMC.psm1 @@ -900,4 +900,112 @@ Function Get-VMCSDDCSummary { } } -Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork', 'Get-VMCSDDCSummary' \ No newline at end of file +Function Get-VMCPublicIP { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/12/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Retrieves all public IP Addresses for a given SDDC + .DESCRIPTION + This cmdlet retrieves all public IP Address for a given SDDC + .EXAMPLE + Get-VMCPublicIP -OrgName $OrgName -SDDCName $SDDCName + #> + Param ( + [Parameter(Mandatory=$True)]$OrgName, + [Parameter(Mandatory=$True)]$SDDCName + ) + + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + + $publicIPService = Get-VmcService "com.vmware.vmc.orgs.sddcs.publicips" + $publicIPs = $publicIPService.list($orgId,$sddcId) + + $publicIPs | select public_ip, name, allocation_id + } + } + + Function New-VMCPublicIP { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/12/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Request a new public IP Address for a given SDDC + .DESCRIPTION + This cmdlet requests a new public IP Address for a given SDDC + .EXAMPLE + New-VMCPublicIP -OrgName $OrgName -SDDCName $SDDCName -Description "Test for Randy" + #> + Param ( + [Parameter(Mandatory=$True)]$OrgName, + [Parameter(Mandatory=$True)]$SDDCName, + [Parameter(Mandatory=$False)]$Description + ) + + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + + $publicIPService = Get-VmcService "com.vmware.vmc.orgs.sddcs.publicips" + + $publicIPSpec = $publicIPService.Help.create.spec.Create() + $publicIPSpec.count = 1 + $publicIPSpec.names = @($Description) + + Write-Host "Requesting a new public IP Address for your SDDC ..." + $results = $publicIPService.create($orgId,$sddcId,$publicIPSpec) + } + } + + Function Remove-VMCPublicIP { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/12/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes a specific public IP Addresses for a given SDDC + .DESCRIPTION + This cmdlet removes a specific public IP Address for a given SDDC + .EXAMPLE + Remove-VMCPublicIP -OrgName $OrgName -SDDCName $SDDCName -AllocationId "eipalloc-0567acf34e436c01f" + #> + Param ( + [Parameter(Mandatory=$True)]$OrgName, + [Parameter(Mandatory=$True)]$SDDCName, + [Parameter(Mandatory=$True)]$AllocationId + ) + + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + + $publicIPService = Get-VmcService "com.vmware.vmc.orgs.sddcs.publicips" + + Write-Host "Deleting public IP Address with ID $AllocationId ..." + $results = $publicIPService.delete($orgId,$sddcId,$AllocationId) + } + } + +Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork', 'Get-VMCSDDCSummary', 'New-VMCPublicIP', '', 'Remove-VMCPublicIP' \ No newline at end of file From 5b74c582b796a74b8c4758eb770aa5799aac736c Mon Sep 17 00:00:00 2001 From: William Lam Date: Wed, 12 Sep 2018 12:23:37 -0700 Subject: [PATCH 25/50] Fixing typo --- Modules/VMware.VMC/VMware.VMC.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/VMware.VMC/VMware.VMC.psm1 b/Modules/VMware.VMC/VMware.VMC.psm1 index 919bea2..6605a14 100644 --- a/Modules/VMware.VMC/VMware.VMC.psm1 +++ b/Modules/VMware.VMC/VMware.VMC.psm1 @@ -1008,4 +1008,4 @@ Function Get-VMCPublicIP { } } -Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork', 'Get-VMCSDDCSummary', 'New-VMCPublicIP', '', 'Remove-VMCPublicIP' \ No newline at end of file +Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork', 'Get-VMCSDDCSummary', 'Get-VMCPublicIP', 'New-VMCPublicIP', 'Remove-VMCPublicIP' From c34b602bf327bb7afc98e3266b6966561f8565d9 Mon Sep 17 00:00:00 2001 From: AndyG Date: Fri, 14 Sep 2018 08:58:53 -0400 Subject: [PATCH 26/50] Get-NSXTRoutingTable & Get-NSXTForwardingTable now work Get-NSXTRoutingTable & Get-NSXTForwardingTable now work. Thanks for Nick from VMW for pointing out the .help was incorrect and submitting a PR to update the API guide. --- Modules/NSXT/NSXT.psd1 | 18 ++- Modules/NSXT/NSXT.psm1 | 318 +++++++++++++++++++++++++++++++++++++++-- 2 files changed, 322 insertions(+), 14 deletions(-) diff --git a/Modules/NSXT/NSXT.psd1 b/Modules/NSXT/NSXT.psd1 index d9e25bc..01b05f0 100644 --- a/Modules/NSXT/NSXT.psd1 +++ b/Modules/NSXT/NSXT.psd1 @@ -7,7 +7,23 @@ Copyright = '(c) 2017. All rights reserved.' Description = 'Powershell Module for NSX-T REST API Functions' PowerShellVersion = '5.0' - FunctionsToExport = 'Get-NSXTComputeManager','Get-NSXTFabricNode','Get-NSXTFirewallRule','Get-NSXTIPPool','Get-NSXTLogicalSwitch','Get-NSXTManager','Get-NSXTTransportZone','Get-NSXTController','Get-NSXTTransportNodes' + FunctionsToExport = 'Get-NSXTComputeManager', + 'Get-NSXTFabricNode', + 'Get-NSXTFirewallRule', + 'Get-NSXTIPPool', + 'Get-NSXTLogicalSwitch', + 'Get-NSXTManager', + 'Get-NSXTTransportZone', + 'Get-NSXTController', + 'Get-NSXTTransportNodes', + 'Get-NSXTTraceFlow', + 'Get-NSXTEdgeCluster', + 'Get-NSXTLogicalRouter', + 'Get-NSXTRoutingTable', + 'Get-NSXTFabricVM', + 'Get-NSXTBGPNeighbors', + 'Get-NSXTForwardingTable', + 'Get-NSXTNetworkRoutes' PrivateData = @{ PSData = @{ Tags = @('NSX-T','REST') diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index c68b135..bc95e6d 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -573,10 +573,18 @@ Function Get-NSXTLogicalRouter { begin { $NSXTLogicalRoutersService = Get-NsxtService -Name "com.vmware.nsx.logical_routers" - + $NSXTLogicalRoutersStatusService = Get-NsxtService -Name "com.vmware.nsx.logical_routers.status" + + class per_node_status { + $service_router_id = [System.Collections.ArrayList]::new() + [ValidateSet("ACTIVE","STANDBY","DOWN","SYNC","UNKNOWN")] + $high_availability_status = [System.Collections.ArrayList]::new() + } + class NSXTLogicalRouter { [string]$Name [string]$Logical_router_id + [string]$protection hidden [string]$Tags [string]$edge_cluster_id [ValidateSet("TIER0","TIER1")] @@ -587,6 +595,9 @@ Function Get-NSXTLogicalRouter { [string]$failover_mode [string]$external_transit [string]$internal_transit + hidden [string]$advanced_config = [System.Collections.Generic.List[string]]::new() + hidden [string]$firewall_sections = [System.Collections.Generic.List[string]]::new() + $per_node_status = [per_node_status]::new() } } @@ -600,16 +611,26 @@ Function Get-NSXTLogicalRouter { foreach ($NSXLogicalRouter in $NSXLogicalRouters) { + $NSXTLogicalRoutersStatus = $NSXTLogicalRoutersStatusService.get($NSXLogicalRouter.id) $results = [NSXTLogicalRouter]::new() + + foreach ($NSXTLogicalRouterStatus in $NSXTLogicalRoutersStatus.per_node_status) { + $results.per_node_status.service_router_id.add($NSXTLogicalRouterStatus.service_router_id) 1>$null + $results.per_node_status.high_availability_status.add($NSXTLogicalRouterStatus.high_availability_status) 1>$null + } + $results.Name = $NSXLogicalRouter.display_name; $results.Logical_router_id = $NSXLogicalRouter.Id; + $results.protection = $NSXLogicalRouter.protection; $results.Tags = $NSXLogicalRouter.tags; $results.edge_cluster_id = $NSXLogicalRouter.edge_cluster_id; $results.router_type = $NSXLogicalRouter.router_type; $results.high_availability_mode = $NSXLogicalRouter.high_availability_mode; $results.failover_mode =$NSXLogicalRouter.failover_mode; $results.external_transit = $NSXLogicalRouter.advanced_config.external_transit_networks; - $results.internal_transit = $NSXLogicalRouter.advanced_config.internal_transit_network + $results.internal_transit = $NSXLogicalRouter.advanced_config.internal_transit_network; + $results.advanced_config =$NSXLogicalRouter.advanced_config; + $results.firewall_sections =$NSXLogicalRouter.firewall_sections write-output $results } } @@ -620,28 +641,299 @@ Function Get-NSXTRoutingTable { [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] [string]$Logical_router_id, [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] - [string]$Tranport_node_id + [string]$transport_node_id ) Begin { $NSXTRoutingTableService = Get-NsxtService -Name "com.vmware.nsx.logical_routers.routing.route_table" - class NSXTRoutingTable { - [string]$Name - hidden [string]$Id - hidden $tags = [System.Collections.Generic.List[string]]::new() - #more things need to be added when .list actually works + class NSXTRoutingTable { + hidden [string]$Logical_router_id + [string]$lr_component_id + [string]$lr_component_type + [string]$network + [string]$next_hop + [string]$route_type + hidden [string]$logical_router_port_id + [long]$admin_distance + } + } + + Process + { + $NSXTRoutingTable = $NSXTRoutingTableService.list($Logical_router_id,$transport_node_id,$null,$null,$null,$null,$null,'realtime') + + foreach ($NSXTRoute in $NSXTRoutingTable.results) { + + $results = [NSXTRoutingTable]::new() + $results.Logical_router_id = $Logical_router_id; + $results.lr_component_type = $NSXTRoute.lr_component_type; + $results.lr_component_id = $NSXTRoute.lr_component_id; + $results.next_hop = $NSXTRoute.next_hop; + $results.route_type = $NSXTRoute.route_type; + $results.logical_router_port_id = $NSXTRoute.logical_router_port_id; + $results.admin_distance = $NSXTRoute.admin_distance; + $results.network = $NSXTRoute.network + write-output $results + } + } +} + +Function Get-NSXTFabricVM { + + Begin + { + $NSXTVMService = Get-NsxtService -Name "com.vmware.nsx.fabric.virtual_machines" + + class NSXVM { + [string]$Name + $resource_type + hidden [string]$Tags + hidden $compute_ids + hidden [string]$external_id + [string]$host_id + [string]$power_state + [string]$type + hidden $source + } + } + + Process + { + + $NSXTVMs = $NSXTVMService.list().results + + foreach ($NSXTVM in $NSXTVMs) { + + $results = [NSXVM]::new() + $results.Name = $NSXTVM.display_name; + $results.resource_type = $NSXTVM.resource_type; + $results.compute_ids = $NSXTVM.compute_ids; + $results.resource_type = $NSXTVM.resource_type; + $results.Tags = $NSXTVM.tags; + $results.external_id = $NSXTVM.external_id; + $results.host_id = $NSXTVM.host_id; + $results.power_state = $NSXTVM.power_state; + $results.type = $NSXTVM.type; + $results.source = $NSXTVM.source + write-output $results + } + } +} + +Function Get-NSXTBGPNeighbors { + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$logical_router_id + ) + + begin + { + $NSXTThingsService = Get-NsxtService -Name "com.vmware.nsx.logical_routers.routing.bgp.neighbors" + + class NSXTBGPNeighbors { + [string]$Name + [string]$logical_router_id + hidden $tags = [System.Collections.Generic.List[string]]::new() + [string]$protection + [string]$resource_type + [string]$address_families = [System.Collections.Generic.List[string]]::new() + hidden $bfd_config + [bool]$enable_bfd + [bool]$enabled + hidden $filter_in_ipprefixlist_id + hidden $filter_in_routemap_id + hidden $filter_out_ipprefixlist_id + hidden $filter_out_routemap_id + hidden [long]$hold_down_timer + hidden [long]$keep_alive_timer + hidden [long]$maximum_hop_limit + [string]$neighbor_address + hidden [string]$password + [long]$remote_as + [string]$remote_as_num + [string]$source_address + [string]$source_addresses = [System.Collections.Generic.List[string]]::new() + } + } + + Process + { + $NSXTThings = $NSXTThingsService.list($logical_router_id).results + + foreach ($NSXTThing in $NSXTThings) { + + $results = [NSXTBGPNeighbors]::new() + $results.Name = $NSXTThing.display_name; + $results.logical_router_id = $NSXTThing.logical_router_id; + $results.tags = $NSXTThing.tags; + $results.protection = $NSXTThing.protection; + $results.resource_type = $NSXTThing.resource_type; + $results.address_families = $NSXTThing.address_families; + $results.bfd_config = $NSXTThing.bfd_config; + $results.enable_bfd = $NSXTThing.enable_bfd; + $results.enabled = $NSXTThing.enabled; + $results.filter_in_ipprefixlist_id = $NSXTThing.filter_in_ipprefixlist_id; + $results.filter_in_routemap_id = $NSXTThing.filter_in_routemap_id; + $results.filter_out_ipprefixlist_id = $NSXTThing.filter_out_ipprefixlist_id; + $results.filter_out_routemap_id = $NSXTThing.filter_out_routemap_id; + $results.hold_down_timer = $NSXTThing.hold_down_timer; + $results.keep_alive_timer = $NSXTThing.keep_alive_timer; + $results.maximum_hop_limit = $NSXTThing.maximum_hop_limit; + $results.neighbor_address = $NSXTThing.neighbor_address; + $results.password = $NSXTThing.password; + $results.remote_as = $NSXTThing.remote_as; + $results.remote_as_num = $NSXTThing.remote_as_num; + $results.source_address = $NSXTThing.source_address; + $results.source_addresses = $NSXTThing.source_addresses + write-output $results + } + } +} + +Function Get-NSXTForwardingTable { + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [string]$Logical_router_id, + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [string]$transport_node_id + ) + + Begin + { + $NSXTForwardingTableService = Get-NsxtService -Name "com.vmware.nsx.logical_routers.routing.forwarding_table" + + class NSXTForwardingTable { + hidden [string]$Logical_router_id + [string]$lr_component_id + [string]$lr_component_type + [string]$network + [string]$next_hop + [string]$route_type + hidden [string]$logical_router_port_id } } Process { - $NSXTRoutingTable = [NSXTRoutingTable]::new() + $NSXTForwardingTable = $NSXTForwardingTableService.list($Logical_router_id,$transport_node_id,$null,$null,$null,$null,$null,$null,'realtime') - # this does not work, bug report submitted to PowerCLI team - $NSXTRoutingTable = $NSXTRoutingTableService.list($Logical_router_id, $transport_node_id) - - write-output $NSXTRoutingTable + foreach ($NSXTForwarding in $NSXTForwardingTable.results) { + + $results = [NSXTForwardingTable]::new() + $results.Logical_router_id = $Logical_router_id; + $results.lr_component_type = $NSXTForwarding.lr_component_type; + $results.lr_component_id = $NSXTForwarding.lr_component_id; + $results.network = $NSXTForwarding.network; + $results.next_hop = $NSXTForwarding.next_hop; + $results.route_type = $NSXTForwarding.route_type; + $results.logical_router_port_id = $NSXTForwarding.logical_router_port_id + write-output $results + } } } + + Function Get-NSXTNetworkRoutes { + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [string]$route_id + ) + + Begin + { + $NSXTNetworkRoutesService = Get-NsxtService -Name "com.vmware.nsx.node.network.routes" + + class NSXTNetworkRoutes { + [string]$route_id + $route_type + $interface_id + $gateway + $from_address + $destination + $netmask + $metric + $proto + $scope + $src + } + } + + Process + { + if ($route_id) { + $NSXTNetworkRoutes = $NSXTNetworkRoutesService.get($route_id) + } + else { + $NSXTNetworkRoutes = $NSXTNetworkRoutesService.list().results + } + + foreach ($NSXTRoute in $NSXTNetworkRoutes) { + + $results = [NSXTNetworkRoutes]::new() + $results.route_id = $NSXTRoute.route_id; + $results.route_type = $NSXTRoute.route_type; + $results.interface_id = $NSXTRoute.interface_id; + $results.gateway = $NSXTRoute.gateway; + $results.from_address = $NSXTRoute.from_address; + $results.destination = $NSXTRoute.destination; + $results.netmask = $NSXTRoute.netmask; + $results.metric = $NSXTRoute.metric; + $results.proto = $NSXTRoute.proto; + $results.scope = $NSXTRoute.scope; + $results.src = $NSXTRoute.src + write-output $results + } + } +} + +# Get Template +Function Get-NSXTThingTemplate { + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$Thing_id + ) + + begin + { + $NSXTThingsService = Get-NsxtService -Name "com.vmware.nsx.API.Thing" + + class NSXTThing { + [string]$Name + [string]$Thing1 + hidden [string]$Tags = [System.Collections.Generic.List[string]]::new() + [string]$Thing2 + #[ValidateSet("TIER0","TIER1")] + [string]$Thing3 + #[ValidateSet("ACTIVE_ACTIVE","ACTIVE_STANDBY","")] + [string]$Thing4 + #[ValidateSet("PREEMPTIVE","NON_PREEMPTIVE","")] + [string]$Thing5 + [string]$Thing6 + [string]$Thing7 + } + } + + Process + { + if($Thing_id) { + $NSXTThings = $NSXTThingsService.get($Thing_id) + } else { + $NSXTThings = $NSXTThingsService.list().results + } + + foreach ($NSXTThing in $NSXTThings) { + + $results = [NSXTThing]::new() + $results.Name = $NSXTThing.display_name; + $results.Logical_router_id = $NSXTThing.Id; + $results.Tags = $NSXTThing.tags; + $results.thing1 = $NSXTThing.thing1; + $results.thing2 = $NSXTThing.thing2 + + write-output $results + } + } +} \ No newline at end of file From 2103438f8a74bd2059ed3a5729df87ca237e2b94 Mon Sep 17 00:00:00 2001 From: AndyG Date: Fri, 14 Sep 2018 12:27:31 -0400 Subject: [PATCH 27/50] Added Help & Get-NSXTLogicalRouterPorts Added Help & Get-NSXTLogicalRouterPorts --- Modules/NSXT/NSXT.psd1 | 3 +- Modules/NSXT/NSXT.psm1 | 303 +++++++++++++++++++++++++++++++++++++---- 2 files changed, 275 insertions(+), 31 deletions(-) diff --git a/Modules/NSXT/NSXT.psd1 b/Modules/NSXT/NSXT.psd1 index 01b05f0..46ddd8d 100644 --- a/Modules/NSXT/NSXT.psd1 +++ b/Modules/NSXT/NSXT.psd1 @@ -23,7 +23,8 @@ 'Get-NSXTFabricVM', 'Get-NSXTBGPNeighbors', 'Get-NSXTForwardingTable', - 'Get-NSXTNetworkRoutes' + 'Get-NSXTNetworkRoutes', + 'Get-NSXTLogicalRouterPorts' PrivateData = @{ PSData = @{ Tags = @('NSX-T','REST') diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index bc95e6d..145ba10 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -260,6 +260,17 @@ Function Get-NSXTManager { } Function Get-NSXTTransportNode { + <# + .Synopsis + Retrieves the transport_node information + .DESCRIPTION + Retrieves transport_node information for a single or multiple IDs. Execute with no parameters to get all ports, specify a transport_node if known. + .EXAMPLE + Get-NSXTTransportNode + .EXAMPLE + Get-NSXTThingTemplate -Tranport_node_id "TN ID" +#> + Param ( [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] [Alias("Id","Tranportnode_id")] @@ -272,7 +283,7 @@ Function Get-NSXTTransportNode { class NSXTransportNode { [string]$Name - [string]$Tranport_node_id + [string]$Transport_node_id [string]$maintenance_mode hidden $tags = [System.Collections.Generic.List[string]]::new() hidden $host_switches = [System.Collections.Generic.List[string]]::new() @@ -293,19 +304,30 @@ Function Get-NSXTTransportNode { $results = [NSXTransportNode]::new() $results.Name = $NSXTransportNode.display_name; - $results.Tranport_node_id = $NSXTransportNode.Id; + $results.Transport_node_id = $NSXTransportNode.Id; $results.maintenance_mode = $NSXTransportNode.maintenance_mode; $results.Tags = $NSXTransportNode.tags; $results.host_switches = $NSXTransportNode.host_switches; $results.host_switch_spec = $NSXTransportNode.host_switch_spec; $results.transport_zone_endpoints = $NSXTransportNode.transport_zone_endpoints; $results.host_switches = $NSXTransportNode.host_switches - write-output $results + $results } } } Function Get-NSXTTraceFlow { + <# + .Synopsis + Retrieves traceflow information + .DESCRIPTION + Retrieves traceflow information for a single or multiple traceflows. Execute with no parameters to get all traceflows, specify a traceflow_id if known. + .EXAMPLE + Get-NSXTTraceFlow + .EXAMPLE + Get-NSXTTraceFlow -traceflow_id "TF ID +#> + Param ( [parameter(Mandatory=$false,ValueFromPipeline=$true)] [Alias("Id")] @@ -341,11 +363,22 @@ Function Get-NSXTTraceFlow { $results.received = $NSXTraceFlow.Counters.received_count; $results.dropped = $NSXTraceFlow.Counters.dropped_count; $results.analysis = $NSXTraceFlow.analysis - write-output $results + $results } } Function Get-NSXTTraceFlowObservations { + <# + .Synopsis + Retrieves traceflow observations information + .DESCRIPTION + Retrieves traceflow observations information for a single traceflow. Must specify a current traceflow_id + .EXAMPLE + Get-NSXTTraceFlowObservations -traceflow_id "TF ID" + .EXAMPLE + Get-NSXTTraceFlow | Get-NSXTTraceFlowObservations +#> + Param ( [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] [Alias("Id")] @@ -370,6 +403,19 @@ Function Get-NSXTTraceFlowObservations { } Function Set-NSXTTraceFlow { + <# + .Synopsis + Creates a TraceFlow + .DESCRIPTION + Create a TraceFlow for later observation. + .EXAMPLE + Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" + .EXAMPLE + Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" | Get-NSXTTraceFlow + .EXAMPLE + Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" | Get-NSXTTraceFlow | Get-NSXTTraceFlowObservations +#> + [CmdletBinding()] # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types @@ -498,22 +544,28 @@ Function Set-NSXTTraceFlow { catch { - $Error[0].Exception.ServerError.data + throw $Error[0].Exception.ServerError.data # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. Filter by MONITORING. } - } - End - { - # Likely don't need this and will replace with write-output $NSXTraceFlow but I can't test right now due to bug - if ($NSXTraceFlow) - { - Get-NSXttraceflow - } + $NSXTraceFlow } } Function Get-NSXTEdgeCluster { + <# + .Synopsis + Retrieves the Edge cluster information + .DESCRIPTION + Retrieves Edge cluster information for a single or multiple clusterss. Execute with no parameters to get all ports, specify a edge_cluster_id if known. + .EXAMPLE + Get-NSXTEdgeCluster + .EXAMPLE + Get-NSXTEdgeCluster -edge_cluster_id "Edge Cluster ID" + .EXAMPLE + Get-NSXTThingTemplate | where name -eq "My Edge Cluster Name" +#> + Param ( [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] [Alias("Id")] @@ -558,12 +610,27 @@ Function Get-NSXTEdgeCluster { $results.member_node_type = $NSXEdgeCluster.member_node_type; $results.members = $NSXEdgeCluster.members; $results.cluster_profile_bindings = $NSXEdgeCluster.cluster_profile_bindings - write-output $results + $results } } } Function Get-NSXTLogicalRouter { + <# + .Synopsis + Retrieves the Logical Router information + .DESCRIPTION + Retrieves Logical Router information for a single or multiple LR's. This includes corresponding SR's and transport_node_id. Execute with no parameters to get all ports, specify a Logical_router_id if known. + .EXAMPLE + Get-NSXTLogicalRouter + .EXAMPLE + Get-NSXTLogicalRouter -Logical_router_id "LR ID" + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" + .EXAMPLE + (Get-NSXTLogicalRouter -Logical_router_id "LR ID").per_node_status +#> + Param ( [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] [Alias("Id")] @@ -576,9 +643,22 @@ Function Get-NSXTLogicalRouter { $NSXTLogicalRoutersStatusService = Get-NsxtService -Name "com.vmware.nsx.logical_routers.status" class per_node_status { - $service_router_id = [System.Collections.ArrayList]::new() + $service_router_id [ValidateSet("ACTIVE","STANDBY","DOWN","SYNC","UNKNOWN")] - $high_availability_status = [System.Collections.ArrayList]::new() + $high_availability_status + $transport_node_id + + per_node_status(){} + + per_node_status( + $service_router_id, + $high_availability_status, + $transport_node_id + ) { + $this.service_router_id = $service_router_id + $this.high_availability_status = $high_availability_status + $this.transport_node_id = $transport_node_id + } } class NSXTLogicalRouter { @@ -597,7 +677,7 @@ Function Get-NSXTLogicalRouter { [string]$internal_transit hidden [string]$advanced_config = [System.Collections.Generic.List[string]]::new() hidden [string]$firewall_sections = [System.Collections.Generic.List[string]]::new() - $per_node_status = [per_node_status]::new() + $per_node_status = [System.Collections.Generic.List[string]]::new() } } @@ -613,10 +693,9 @@ Function Get-NSXTLogicalRouter { $NSXTLogicalRoutersStatus = $NSXTLogicalRoutersStatusService.get($NSXLogicalRouter.id) $results = [NSXTLogicalRouter]::new() - + foreach ($NSXTLogicalRouterStatus in $NSXTLogicalRoutersStatus.per_node_status) { - $results.per_node_status.service_router_id.add($NSXTLogicalRouterStatus.service_router_id) 1>$null - $results.per_node_status.high_availability_status.add($NSXTLogicalRouterStatus.high_availability_status) 1>$null + $results.per_node_status += [per_node_status]::new($NSXTLogicalRouterStatus.service_router_id,$NSXTLogicalRouterStatus.high_availability_status,$NSXTLogicalRouterStatus.transport_node_id) } $results.Name = $NSXLogicalRouter.display_name; @@ -631,12 +710,27 @@ Function Get-NSXTLogicalRouter { $results.internal_transit = $NSXLogicalRouter.advanced_config.internal_transit_network; $results.advanced_config =$NSXLogicalRouter.advanced_config; $results.firewall_sections =$NSXLogicalRouter.firewall_sections - write-output $results + $results } } } Function Get-NSXTRoutingTable { + <# + .Synopsis + Retrieves the routing table information + .DESCRIPTION + Retrieves routing table for a single LR including LR type (SR/DR) and next_hop. Must specify Logical_router_id & transport_node_id. Pipeline input supported. + .EXAMPLE + Get-NSXTRoutingTable -Logical_router_id "LR ID" -transport_node_id "TN ID" | format-table -autosize + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" | Get-NSXTRoutingTable -transport_node_id "TN ID" + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq INT-T1 | Get-NSXTRoutingTable -transport_node_id ((Get-NSXTTransportNode | where name -match "INT")[0].transport_node_id) + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq INT-T1 | Get-NSXTRoutingTable -transport_node_id (((Get-NSXTLogicalRouter | where name -eq INT-T1).per_node_status | where high_availability_status -eq ACTIVE).transport_node_id) +#> + Param ( [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] [string]$Logical_router_id, @@ -675,13 +769,20 @@ Function Get-NSXTRoutingTable { $results.logical_router_port_id = $NSXTRoute.logical_router_port_id; $results.admin_distance = $NSXTRoute.admin_distance; $results.network = $NSXTRoute.network - write-output $results + $results } } } Function Get-NSXTFabricVM { - + <# + .Synopsis + Retrieves the VM's attached to the fabric. + .DESCRIPTION + Retrieves all VM's attached to the fabric. + .EXAMPLE + Get-NSXTFabricVM +#> Begin { $NSXTVMService = Get-NsxtService -Name "com.vmware.nsx.fabric.virtual_machines" @@ -717,12 +818,23 @@ Function Get-NSXTFabricVM { $results.power_state = $NSXTVM.power_state; $results.type = $NSXTVM.type; $results.source = $NSXTVM.source - write-output $results + $results } } } Function Get-NSXTBGPNeighbors { + <# + .Synopsis + Retrieves the BGP neighbor information + .DESCRIPTION + Retrieves BGP neighbor information for a single logical router. Must specify logical_router_id parameter. Pipeline input supported + .EXAMPLE + Get-NSXTBGPNeighbors -logical_router_id "LR ID" + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" | Get-NSXTBGPNeighbors +#> + Param ( [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] [Alias("Id")] @@ -788,12 +900,27 @@ Function Get-NSXTBGPNeighbors { $results.remote_as_num = $NSXTThing.remote_as_num; $results.source_address = $NSXTThing.source_address; $results.source_addresses = $NSXTThing.source_addresses - write-output $results + $results } } } Function Get-NSXTForwardingTable { + <# + .Synopsis + Retrieves the forwarding table information + .DESCRIPTION + Retrieves forwarding table for a single LR including LR type (SR/DR) and next_hop. Must specify Logical_router_id & transport_node_id. Pipeline input supported. + .EXAMPLE + Get-Get-NSXTForwardingTable -Logical_router_id "LR ID" -transport_node_id "TN ID" | format-table -autosize + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" | Get-NSXTForwardingTable -transport_node_id "TN ID" + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" | Get-NSXTForwardingTable -transport_node_id ((Get-NSXTTransportNode | where name -match "Edge Name")[0].transport_node_id) + .EXAMPLE + Get-NSXTLogicalRouter | where name -eq "LR Name" | Get-NSXTForwardingTable -transport_node_id (((Get-NSXTLogicalRouter | where name -eq "Edge Name").per_node_status | where high_availability_status -eq ACTIVE).transport_node_id) +#> + Param ( [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] [string]$Logical_router_id, @@ -830,12 +957,23 @@ Function Get-NSXTForwardingTable { $results.next_hop = $NSXTForwarding.next_hop; $results.route_type = $NSXTForwarding.route_type; $results.logical_router_port_id = $NSXTForwarding.logical_router_port_id - write-output $results + $results } } } - Function Get-NSXTNetworkRoutes { +Function Get-NSXTNetworkRoutes { +<# + .Synopsis + Retrieves the network routes information + .DESCRIPTION + Retrieves the network routes information for a single or multiple routes. + .EXAMPLE + Get-NSXTNetworkRoutes + .EXAMPLE + Get-NSXTNetworkRoutes -route_id "Route ID" +#> + Param ( [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] [string]$route_id @@ -883,13 +1021,118 @@ Function Get-NSXTForwardingTable { $results.proto = $NSXTRoute.proto; $results.scope = $NSXTRoute.scope; $results.src = $NSXTRoute.src - write-output $results + $results } } } +Function Get-NSXTLogicalRouterPorts { +<# + .Synopsis + Retrieves the logical router port information + .DESCRIPTION + Retrieves logical router port information for a single or multiple ports. Execute with no parameters to get all ports, specify a single port if known, or feed a logical switch for filtered output. + .EXAMPLE + Get-NSXTLogicalRouterPorts + .EXAMPLE + Get-NSXTLogicalRouterPorts -logical_router_port_id "LR Port Name" + .EXAMPLE + Get-NSXTLogicalRouterPorts -logical_router_id "LR Name" + .EXAMPLE + Get-NSXTLogicalRouterPorts -logical_router_id (Get-NSXTLogicalRouter | where name -eq "LR Name") +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$logical_router_port_id, + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [string]$logical_router_id + ) + + begin + { + $NSXTLogicalRouterPortsService = Get-NsxtService -Name "com.vmware.nsx.logical_router_ports" + + class subnets { + $ip_addresses + $prefix_length + + subnets(){} + + subnets( + $ip_addresses, + $prefix_length + ) { + $this.ip_addresses = $ip_addresses + $this.prefix_length = $prefix_length + } + } + + class NSXTLogicalRouterPorts { + [string]$Name + $Id + [string]$logical_router_id + $resource_type + [string]$protection + $mac_address + $subnets = [System.Collections.Generic.List[string]]::new() + hidden [string]$Tags + hidden $linked_logical_switch_port_id + } + } + + Process + { + if($logical_router_port_id) { + $NSXTLogicalRouterPorts = $NSXTLogicalRouterPortsService.get($logical_router_port_id) + } else { + if ($logical_router_id) { + $NSXTLogicalRouterPorts = $NSXTLogicalRouterPortsService.list().results | where {$_.logical_router_id -eq $Logical_router_id} + } + else { + $NSXTLogicalRouterPorts = $NSXTLogicalRouterPortsService.list().results + } + } + + foreach ($NSXTLogicalRouterPort in $NSXTLogicalRouterPorts) { + + $results = [NSXTLogicalRouterPorts]::new() + + foreach ($subnet in $NSXTLogicalRouterPort.subnets) { + $results.subnets += [subnets]::new($subnet.ip_addresses,$subnet.prefix_length) + } + + $results.Name = $NSXTLogicalRouterPort.display_name + $results.Id = $NSXTLogicalRouterPort.Id + $results.Logical_router_id = $NSXTLogicalRouterPort.Logical_router_id + $results.resource_type = $NSXTLogicalRouterPort.resource_type + $results.protection = $NSXTLogicalRouterPort.protection + $results.Tags = $NSXTLogicalRouterPort.tags + $results.mac_address = $NSXTLogicalRouterPort.mac_address + $results.linked_logical_switch_port_id = $NSXTLogicalRouterPort.linked_logical_switch_port_id + $results + } + } +} + # Get Template Function Get-NSXTThingTemplate { + <# + .Synopsis + Retrieves the THING information + .DESCRIPTION + Retrieves THING information for a single or multiple ports. Execute with no parameters to get all ports, specify a PARAM if known. + .EXAMPLE + Get-NSXTThingTemplate + .EXAMPLE + Get-NSXTThingTemplate -param1 "LR Port Name" + .EXAMPLE + Get-NSXTThingTemplate -param2 "LR Name" + .EXAMPLE + Get-NSXTThingTemplate -param2 (Get-NSXTLogicalRouter | where name -eq "LR Name") +#> + Param ( [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] [Alias("Id")] @@ -933,7 +1176,7 @@ Function Get-NSXTThingTemplate { $results.thing1 = $NSXTThing.thing1; $results.thing2 = $NSXTThing.thing2 - write-output $results + $results } } -} \ No newline at end of file +} From 9a4acf5c57445e90cde776f3b17cf3887915e888 Mon Sep 17 00:00:00 2001 From: AndyG Date: Fri, 14 Sep 2018 15:51:11 -0400 Subject: [PATCH 28/50] Adding Set Commands Adding Set Commands --- Modules/NSXT/NSXT.psd1 | 32 +- Modules/NSXT/NSXT.psm1 | 994 +++++++++++++++++++++++++++++++---------- 2 files changed, 773 insertions(+), 253 deletions(-) diff --git a/Modules/NSXT/NSXT.psd1 b/Modules/NSXT/NSXT.psd1 index 46ddd8d..1ebab1e 100644 --- a/Modules/NSXT/NSXT.psd1 +++ b/Modules/NSXT/NSXT.psd1 @@ -7,24 +7,32 @@ Copyright = '(c) 2017. All rights reserved.' Description = 'Powershell Module for NSX-T REST API Functions' PowerShellVersion = '5.0' - FunctionsToExport = 'Get-NSXTComputeManager', + FunctionsToExport = 'Get-NSXTBGPNeighbors', + 'Get-NSXTComputeManager', + 'Get-NSXTController', + 'Get-NSXTEdgeCluster', 'Get-NSXTFabricNode', + 'Get-NSXTFabricVM', 'Get-NSXTFirewallRule', + 'Get-NSXTForwardingTable', 'Get-NSXTIPPool', + 'Get-NSXTLogicalRouter', + 'Get-NSXTLogicalRouterPorts', 'Get-NSXTLogicalSwitch', 'Get-NSXTManager', - 'Get-NSXTTransportZone', - 'Get-NSXTController', - 'Get-NSXTTransportNodes', - 'Get-NSXTTraceFlow', - 'Get-NSXTEdgeCluster', - 'Get-NSXTLogicalRouter', - 'Get-NSXTRoutingTable', - 'Get-NSXTFabricVM', - 'Get-NSXTBGPNeighbors', - 'Get-NSXTForwardingTable', 'Get-NSXTNetworkRoutes', - 'Get-NSXTLogicalRouterPorts' + 'Get-NSXTRoutingTable', + 'Get-NSXTThingTemplate', + 'Get-NSXTTraceFlow', + 'Get-NSXTTraceFlowObservations', + 'Get-NSXTTransportNode', + 'Get-NSXTTransportZone', + 'Set-NSXTIPPool', + 'Set-NSXTLogicalRouter', + 'Set-NSXTLogicalSwitch', + 'Set-NSXTThingTemplate', + 'Set-NSXTTraceFlow' + PrivateData = @{ PSData = @{ Tags = @('NSX-T','REST') diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index 145ba10..aa30c32 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -71,63 +71,6 @@ Function Get-NSXTFabricNode { $results } -Function Get-NSXTIPPool { - Param ( - [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id - ) - - $ipPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools" - - if($Id) { - $ipPools = $ipPoolService.get($Id) - } else { - $ipPools = $ipPoolService.list().results - } - - $results = @() - foreach ($ipPool in $ipPools) { - $tmp = [pscustomobject] @{ - Id = $ipPool.Id; - Name = $ipPool.Display_Name; - Total = $ipPool.pool_usage.total_ids; - Free = $ipPool.pool_usage.free_ids; - Network = $ipPool.subnets.cidr; - Gateway = $ipPool.subnets.gateway_ip; - DNS = $ipPool.subnets.dns_nameservers; - RangeStart = $ipPool.subnets.allocation_ranges.start; - RangeEnd = $ipPool.subnets.allocation_ranges.end - } - $results+=$tmp - } - $results -} - -Function Get-NSXTTransportZone { - Param ( - [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id - ) - - $transportZoneService = Get-NsxtService -Name "com.vmware.nsx.transport_zones" - - if($Id) { - $transportZones = $transportZoneService.get($Id) - } else { - $transportZones = $transportZoneService.list().results - } - - $results = @() - foreach ($transportZone in $transportZones) { - $tmp = [pscustomobject] @{ - Id = $transportZone.Id; - Name = $transportZone.display_name; - Type = $transportZone.transport_type; - HostSwitchName = $transportZone.host_switch_name; - } - $results+=$tmp - } - $results -} - Function Get-NSXTComputeManager { Param ( [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id @@ -160,38 +103,6 @@ Function Get-NSXTComputeManager { $results } -Function Get-NSXTLogicalSwitch { - Param ( - [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id - ) - - $logicalSwitchService = Get-NsxtService -Name "com.vmware.nsx.logical_switches" - $logicalSwitchSummaryService = Get-NsxtService -Name "com.vmware.nsx.logical_switches.summary" - - if($Id) { - $logicalSwitches = $logicalSwitchService.get($Id) - } else { - $logicalSwitches = $logicalSwitchService.list().results - } - - $results = @() - foreach ($logicalSwitch in $logicalSwitches) { - $transportZone = (Get-NSXTTransportZone -Id $logicalSwitch.transport_zone_id | Select Name | ft -HideTableHeaders | Out-String).trim() - $ports = $logicalSwitchSummaryService.get($logicalSwitch.id).num_logical_ports - - $tmp = [pscustomobject] @{ - Id = $logicalSwitch.Id; - Name = $logicalSwitch.display_name; - VLAN = $logicalSwitch.vlan; - AdminStatus = $logicalSwitch.admin_state; - Ports = $ports; - TransportZone = $transportZone; - } - $results+=$tmp - } - $results -} - Function Get-NSXTFirewallRule { Param ( [parameter(Mandatory=$false,ValueFromPipeline=$true)][string]$Id @@ -259,6 +170,8 @@ Function Get-NSXTManager { $results } +# Updated Function style below + Function Get-NSXTTransportNode { <# .Synopsis @@ -402,156 +315,6 @@ Function Get-NSXTTraceFlowObservations { } } -Function Set-NSXTTraceFlow { - <# - .Synopsis - Creates a TraceFlow - .DESCRIPTION - Create a TraceFlow for later observation. - .EXAMPLE - Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" - .EXAMPLE - Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" | Get-NSXTTraceFlow - .EXAMPLE - Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" | Get-NSXTTraceFlow | Get-NSXTTraceFlowObservations -#> - - [CmdletBinding()] - - # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types - Param ( - [parameter(Mandatory=$true, - ParameterSetName='Parameter Set VM Type')] - [ValidateSet("UNICAST")] - [string] - $transport_type = "UNICAST", - [parameter(Mandatory=$true, - ValueFromPipeline=$true, - ParameterSetName='Parameter Set VM Type')] - [ValidateNotNullOrEmpty()] - #[ValidateScript({Get-NSXTLogicalPort -Id $_}] - [string] - $lport_id, - [parameter(Mandatory=$true, - ValueFromPipeline=$true, - ParameterSetName='Parameter Set VM Type')] - [ValidateNotNullOrEmpty()] - [ValidateScript({$_ -match [IPAddress]$_})] - [string] - $src_ip, - [parameter(Mandatory=$true, - ValueFromPipeline=$true, - ParameterSetName='Parameter Set VM Type')] - [ValidateNotNullOrEmpty()] - [ValidateScript({$pattern = '^(([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2}))|(([0-9A-Fa-f]{2}[-]){5}([0-9A-Fa-f]{2}))$' - if ($_ -match ($pattern -join '|')) {$true} else { - throw "The argument '$_' does not match a valid MAC address format." - } - })] - [string] - $src_mac, - [parameter(Mandatory=$true, - ValueFromPipeline=$true, - ParameterSetName='Parameter Set VM Type')] - [ValidateNotNullOrEmpty()] - [ValidateScript({$_ -match [IPAddress]$_ })] - [string] - $dst_ip, - [parameter(Mandatory=$true, - ValueFromPipeline=$true, - ParameterSetName='Parameter Set VM Type')] - [ValidateNotNullOrEmpty()] - [ValidateScript({$pattern = '^(([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2}))|(([0-9A-Fa-f]{2}[-]){5}([0-9A-Fa-f]{2}))$' - if ($_ -match ($pattern -join '|')) {$true} else { - throw "The argument '$_' does not match a valid MAC address format." - } - })] - [string] - $dst_mac) - - Begin - { - if (-not $global:DefaultNsxtServers.isconnected) - { - - try - { - Connect-NsxtServer -Menu -ErrorAction Stop - } - - catch - { - throw "Could not connect to an NSX-T Manager, please try again" - } - } - - $NSXTraceFlowsService = Get-NsxtService -Name "com.vmware.nsx.traceflows" - - class ip_header { - [string]$src_ip - [string]$dst_ip - } - - class eth_header { - [string]$src_mac - [string]$dst_mac - } - - class packet_data { - [boolean]$routed - [ValidateSet("UNICAST","BROADCAST","MULTICAST","UNKNOWN")] - [string]$transport_type - [ValidateSet("BINARYPACKETDATA","FIELDSPACKETDATA")] - [string]$resource_type - [long]$frame_size - [eth_header]$eth_header = [eth_header]::new() - [ip_header]$ip_header = [ip_header]::new() - - packet_data(){ - $this.routed = 'true' - $this.transport_type = 'UNICAST' - $this.resource_type = 'FieldsPacketData' - } - } - - class traceflow_request { - [string]$lport_id - [long]$timeout - [packet_data]$packet = [packet_data]::new() - - traceflow_request(){ - $this.timeout = '15000' - } - } - } - - Process - { - [traceflow_request]$traceflow_request = [traceflow_request]::new() - - $traceflow_request.lport_id = $lport_id - $traceflow_request.packet.transport_type = $transport_type - $traceflow_request.packet.eth_header.src_mac = $src_mac - $traceflow_request.packet.eth_header.dst_mac = $dst_mac - $traceflow_request.packet.ip_header.src_ip = $src_ip - $traceflow_request.packet.ip_header.dst_ip = $dst_ip - - try - { - # This does not work, bug report submitted to PowerCLI team - $NSXTraceFlow = $NSXTraceFlowService.create($traceflow_request) - } - - catch - { - throw $Error[0].Exception.ServerError.data - # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. Filter by MONITORING. - } - - $NSXTraceFlow - } -} - Function Get-NSXTEdgeCluster { <# .Synopsis @@ -1116,6 +879,660 @@ Function Get-NSXTLogicalRouterPorts { } } +Function Get-NSXTTransportZone { + <# + .Synopsis + Retrieves the Transport Zone information + .DESCRIPTION + Retrieves THING information for a single or multiple ports. Execute with no parameters to get all ports, specify a PARAM if known. + .EXAMPLE + Get-NSXTTransportZone + .EXAMPLE + Get-NSXTTransportZone -zone_id "Zone ID" + .EXAMPLE + Get-NSXTTransportZone -name "Zone1" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$zone_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTTransportZoneService = Get-NsxtService -Name "com.vmware.nsx.transport_zones" + + class NSXTTransportZone { + [string]$Name + [string]$ID + hidden [string]$description + hidden $tags + $resource_type + $host_switch_name + $transport_type + hidden $transport_zone_profile_ids + $host_switch_mode + $protection + hidden $uplink_teaming_policy_names + } + } + + Process + { + if($zone_id) { + $NSXTTransportZones = $NSXTTransportZoneService.get($zone_id) + } else { + if ($name) { + $NSXTTransportZones = $NSXTTransportZoneService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTTransportZones = $NSXTTransportZoneService.list().results + } + } + + foreach ($NSXTTransportZone in $NSXTTransportZones) { + + $results = [NSXTTransportZone]::new() + $results.Name = $NSXTTransportZone.display_name; + $results.ID = $NSXTTransportZone.Id; + $results.description = $NSXTTransportZone.description; + $results.tags = $NSXTTransportZone.tags; + $results.resource_type = $NSXTTransportZone.resource_type; + $results.host_switch_name = $NSXTTransportZone.host_switch_name; + $results.transport_type = $NSXTTransportZone.transport_type; + $results.transport_zone_profile_ids = $NSXTTransportZone.transport_zone_profile_ids; + $results.host_switch_mode = $NSXTTransportZone.host_switch_mode; + $results.protection = $NSXTTransportZone.protection; + $results.uplink_teaming_policy_names = $NSXTTransportZone.uplink_teaming_policy_names + $results + } + } +} + +Function Get-NSXTLogicalSwitch { + <# + .Synopsis + Retrieves the Logical Switch information + .DESCRIPTION + Retrieves Logical Switch information for a single or multiple switches. Execute with no parameters to get all ports, specify a name or lswitch_id if known. + .EXAMPLE + Get-NSXTLogicalSwitch + .EXAMPLE + Get-NSXTLogicalSwitch -lswitch_id "switch id" + .EXAMPLE + Get-NSXTLogicalSwitch -name "switch name" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$lswitch_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTLogicalSwitchService = Get-NsxtService -Name "com.vmware.nsx.logical_switches" + + class NSXTLogicalSwitch { + [string]$Name + [string]$ID + $tags + $resource_type + hidden $description + $vni + $transport_zone_id + $admin_state + $replication_mode + hidden $address_bindings + $protection + hidden $extra_configs + $ip_pool_id + hidden $mac_pool_id + hidden $uplink_teaming_policy_name + hidden $vlan + hidden $vlan_trunk_spec + } + } + + Process + { + if($lswitch_id) { + $NSXTLogicalSwitches = $NSXTLogicalSwitchService.get($lswitch_id) + } else { + if ($name) { + $NSXTLogicalSwitches = $NSXTLogicalSwitchService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTLogicalSwitches = $NSXTLogicalSwitchService.list().results + } + } + + foreach ($NSXTLogicalSwitch in $NSXTLogicalSwitches) { + + $results = [NSXTLogicalSwitch]::new() + $results.Name = $NSXTLogicalSwitch.display_name; + $results.Id = $NSXTLogicalSwitch.Id; + $results.Tags = $NSXTLogicalSwitch.tags; + $results.resource_type = $NSXTLogicalSwitch.resource_type; + $results.description = $NSXTLogicalSwitch.description; + $results.vni = $NSXTLogicalSwitch.vni; + $results.transport_zone_id = $NSXTLogicalSwitch.transport_zone_id; + $results.admin_state = $NSXTLogicalSwitch.admin_state; + $results.replication_mode = $NSXTLogicalSwitch.replication_mode; + $results.address_bindings = $NSXTLogicalSwitch.address_bindings; + $results.protection = $NSXTLogicalSwitch.protection; + $results.extra_configs = $NSXTLogicalSwitch.extra_configs; + $results.ip_pool_id = $NSXTLogicalSwitch.ip_pool_id; + $results.mac_pool_id = $NSXTLogicalSwitch.mac_pool_id; + $results.uplink_teaming_policy_name = $NSXTLogicalSwitch.uplink_teaming_policy_name; + $results.vlan = $NSXTLogicalSwitch.vlan; + $results.vlan_trunk_spec = $NSXTLogicalSwitch.vlan_trunk_spec + $results + } + } +} + +Function Get-NSXTIPPool { + <# + .Synopsis + Retrieves the THING information + .DESCRIPTION + Retrieves THING information for a single or multiple ports. Execute with no parameters to get all ports, specify a PARAM if known. + .EXAMPLE + Get-NSXTIPPool + .EXAMPLE + Get-NSXTThingTemplate -pool_id "Pool ID" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$pool_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTIPPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools" + + class NSXTIPPool { + [string]$Name + [string]$id + $total_ids + $free_ids + $allocated_ids + $Network + $Gateway + $DNS + $RangeStart + $RangeEnd + } + } + + Process + { + if($pool_id) { + $NSXTIPPools = $NSXTIPPoolService.get($pool_id) + } else { + if ($name) { + $NSXTIPPools = $NSXTIPPoolService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTIPPools = $NSXTIPPoolService.list().results + } + } + + foreach ($NSXTIPPool in $NSXTIPPools) { + + $results = [NSXTIPPool]::new() + $results.Name = $NSXTIPPool.display_name; + $results.ID = $NSXTIPPool.id; + $results.total_ids = $NSXTIPPool.pool_usage.total_ids; + $results.free_ids = $NSXTIPPool.pool_usage.free_ids; + $results.allocated_ids = $NSXTIPPool.pool_usage.allocated_ids; + $results.Network = $NSXTIPPool.subnets.cidr; + $results.Gateway = $NSXTIPPool.subnets.gateway_ip; + $results.DNS = $NSXTIPPool.subnets.dns_nameservers; + $results.RangeStart = $NSXTIPPool.subnets.allocation_ranges.start; + $results.RangeEnd = $NSXTIPPool.subnets.allocation_ranges.end + $results + } + } +} + +# Working Set Functions +Function Set-NSXTLogicalRouter { + <# + .Synopsis + Creates a Logical Router + .DESCRIPTION + Create a TIER0 or TIER1 logical router + .EXAMPLE + Set-NSXTLogicalRouter -display_name "Name" -high_availability_mode "ACTIVE_STANDBY" -router_type "TIER1" + .EXAMPLE + Set-NSXTLogicalRouter -display_name "Name" -high_availability_mode "ACTIVE_ACTIVE" -router_type "TIER0" -edge_cluster_id "Edge Cluster ID" + .EXAMPLE + Set-NSXTLogicalRouter -display_name "Name" -high_availability_mode "ACTIVE_STANDBY" -router_type "TIER1" -description "this is my new tier1 lr" +#> + + [CmdletBinding()] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$false, + ParameterSetName='TIER0')] + [parameter(Mandatory=$false, + ParameterSetName='TIER1')] + [string]$description, + + [parameter(Mandatory=$true, + ParameterSetName='TIER0')] + [parameter(Mandatory=$true, + ParameterSetName='TIER1')] + [string]$display_name, + + [parameter(Mandatory=$true, + ParameterSetName='TIER0')] + [parameter(Mandatory=$true, + ParameterSetName='TIER1')] + [ValidateSet("ACTIVE_ACTIVE","ACTIVE_STANDBY")] + [string]$high_availability_mode, + + [parameter(Mandatory=$true, + ParameterSetName='TIER0')] + [parameter(Mandatory=$true, + ParameterSetName='TIER1')] + [ValidateSet("TIER0","TIER1")] + [string]$router_type, + + [parameter(Mandatory=$true, + ParameterSetName='TIER0')] + [string]$edge_cluster_id + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTLogicalRouterService = Get-NsxtService -Name "com.vmware.nsx.logical_routers" + } + + Process + { + $logical_router_request = $NSXTLogicalRouterService.help.create.logical_router.Create() + + $logical_router_request.display_name = $display_name + $logical_router_request.description = $description + $logical_router_request.router_type = $router_type + $logical_router_request.high_availability_mode = $high_availability_mode + $logical_router_request.resource_type = "LogicalRouter" + $logical_router_request.failover_mode = "NON_PREEMPTIVE" + + if ($edge_cluster_id) { + $logical_router_request.edge_cluster_id = $edge_cluster_id + } + + try + { + # + $NSXTLogicalRouter = $NSXTLogicalRouterService.create($logical_router_request) + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + + $NSXTLogicalRouter + } +} + +Function Set-NSXTLogicalSwitch { + <# + .Synopsis + Creates a Logical Switch + .DESCRIPTION + Creates a Logical Switch with a number of required parameters. IP Pool is necessary even for an overlay logical switch + .EXAMPLE + Set-NSXTLogicalSwitch -display_name "Name" -transport_zone_id "TP Zone ID" + .EXAMPLE + Set-NSXTLogicalSwitch -display_name "Name" -transport_zone_id "TP Zone ID" -admin_state "UP" -replication_mode "MTEP" -ip_pool_id "IP Pool Name" +#> + + [CmdletBinding()] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$false)] + [string]$description, + + [parameter(Mandatory=$true)] + [string]$display_name, + + [parameter(Mandatory=$true)] + [string]$transport_zone_id, + + [parameter(Mandatory=$true)] + [ValidateSet("UP","DOWN")] + [string]$admin_state, + + [parameter(Mandatory=$false)] + [ValidateSet("MTEP","SOURCE")] + [string]$replication_mode, + + [parameter(Mandatory=$true)] + [string]$ip_pool_id + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTLogicalSwitchService = Get-NsxtService -Name "com.vmware.nsx.logical_switches" + } + + Process + { + $logical_switch_request = $NSXTLogicalSwitchService.help.create.logical_switch.Create() + + $logical_switch_request.display_name = $display_name + $logical_switch_request.description = $description + $logical_switch_request.admin_state = $admin_state + $logical_switch_request.transport_zone_id = $transport_zone_id + $logical_switch_request.resource_type = "LogicalSwitch" + $logical_switch_request.replication_mode = $replication_mode + $logical_switch_request.ip_pool_id = $ip_pool_id + + try + { + # + $NSXTLogicalSwitch = $NSXTLogicalSwitchService.create($logical_switch_request) + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + + $NSXTLogicalSwitch + } +} + +# Non-working Set Functions +Function Set-NSXTTraceFlow { + <# + .Synopsis + Creates a TraceFlow + .DESCRIPTION + Create a TraceFlow for later observation. + .EXAMPLE + Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" + .EXAMPLE + Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" | Get-NSXTTraceFlow + .EXAMPLE + Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" | Get-NSXTTraceFlow | Get-NSXTTraceFlowObservations +#> + + [CmdletBinding()] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateSet("UNICAST")] + [string] + $transport_type = "UNICAST", + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + #[ValidateScript({Get-NSXTLogicalPort -Id $_}] + [string] + $lport_id, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$_ -match [IPAddress]$_})] + [string] + $src_ip, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$pattern = '^(([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2}))|(([0-9A-Fa-f]{2}[-]){5}([0-9A-Fa-f]{2}))$' + if ($_ -match ($pattern -join '|')) {$true} else { + throw "The argument '$_' does not match a valid MAC address format." + } + })] + [string] + $src_mac, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$_ -match [IPAddress]$_ })] + [string] + $dst_ip, + [parameter(Mandatory=$true, + ValueFromPipeline=$true, + ParameterSetName='Parameter Set VM Type')] + [ValidateNotNullOrEmpty()] + [ValidateScript({$pattern = '^(([0-9A-Fa-f]{2}[:]){5}([0-9A-Fa-f]{2}))|(([0-9A-Fa-f]{2}[-]){5}([0-9A-Fa-f]{2}))$' + if ($_ -match ($pattern -join '|')) {$true} else { + throw "The argument '$_' does not match a valid MAC address format." + } + })] + [string] + $dst_mac) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTraceFlowsService = Get-NsxtService -Name "com.vmware.nsx.traceflows" + + # Comment out custom classes + <# + class ip_header { + [string]$src_ip + [string]$dst_ip + } + + class eth_header { + [string]$src_mac + [string]$dst_mac + } + + class packet_data { + [boolean]$routed + [ValidateSet("UNICAST","BROADCAST","MULTICAST","UNKNOWN")] + [string]$transport_type + [ValidateSet("BINARYPACKETDATA","FIELDSPACKETDATA")] + [string]$resource_type + [long]$frame_size + [eth_header]$eth_header = [eth_header]::new() + [ip_header]$ip_header = [ip_header]::new() + + packet_data(){ + $this.routed = 'true' + $this.transport_type = 'UNICAST' + $this.resource_type = 'FieldsPacketData' + } + } + + class traceflow_request { + [string]$lport_id + [long]$timeout + [packet_data]$packet = [packet_data]::new() + + traceflow_request(){ + $this.timeout = '15000' + } + } +#> + } + + Process + { + $traceflow_request = $NSXTraceFlowsService.Help.create.traceflow_request.Create() + + $traceflow_request.lport_id = $lport_id + $traceflow_request.packet.transport_type = $transport_type + + $eth_header = [ordered]@{'src_mac' = $src_mac;'eth_type' = '2048';'dst_mac' = $dst_mac} + $ip_header = [ordered]@{src_ip = $src_ip;protocol = '1';ttl = '64';dst_ip = $dst_ip} + $traceflow_request.packet | Add-Member -NotePropertyMembers $eth_header -TypeName eth_header + $traceflow_request.packet | Add-Member -NotePropertyMembers $ip_header -TypeName ip_header + + try + { + # This does not work, bug report submitted to PowerCLI team + $NSXTraceFlow = $NSXTraceFlowService.create($traceflow_request) + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. Filter by MONITORING. + } + + $NSXTraceFlow + } +} + +Function Set-NSXTIPPool { + <# + .Synopsis + Creates an IP Pool + .DESCRIPTION + Creates a IP Pool with a number of required parameters. Supported IP formats include 192.168.1.1, 192.168.1.1-192.168.1.100, 192.168.0.0/24 + .EXAMPLE + Set-NSXTIPPool -display_name "Pool Name" -allocation_start "192.168.1.1" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" + .EXAMPLE + Set-NSXTIPPool -display_name "Pool Name" -allocation_start "192.168.1.1" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" -dns_nameservers "192.168.1.1" -gateway_ip "192.168.1.1" +#> + + [CmdletBinding()] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$true)] + [string]$display_name, + + [parameter(Mandatory=$false)] + [string]$description, + + [parameter(Mandatory=$false)] + [string]$dns_nameservers, + + [parameter(Mandatory=$true)] + [string]$allocation_start, + + [parameter(Mandatory=$true)] + [string]$allocation_end, + + [parameter(Mandatory=$true)] + [string]$cidr, + + [parameter(Mandatory=$false)] + [string]$gateway_ip + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTIPPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools" + } + + Process + { + $ip_pool_request = $NSXTIPPoolService.help.create.ip_pool.Create() + $ip_pool_request.subnets = $NSXTIPPoolService.help.create.ip_pool.subnets.Create() + $ip_pool_request.subnets = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.Create() + $ip_pool_request.subnets.allocation_ranges = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.create() + $ip_pool_request.subnets.allocation_ranges = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.element.create() + + $ip_pool_request.display_name = $display_name + $ip_pool_request.description = $description + $ip_pool_request.resource_type = "IpPool" + $ip_pool_request.subnets.dns_nameservers = $dns_nameservers + $ip_pool_request.subnets.allocation_ranges.start = $allocation_start + $ip_pool_request.subnets.allocation_ranges.end = $allocation_end + $ip_pool_request.subnets.cidr = $cidr + $ip_pool_request.subnets.gateway_ip = $gateway_ip + + try + { + # + $NSXTIPPool = $NSXTIPPoolService.create($ip_pool_request) + } + + catch + { + $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + throw + } + + $NSXTIPPool + } +} + # Get Template Function Get-NSXTThingTemplate { <# @@ -1136,7 +1553,9 @@ Function Get-NSXTThingTemplate { Param ( [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] [Alias("Id")] - [string]$Thing_id + [string]$Thing_id, + [parameter(Mandatory=$false)] + [string]$name ) begin @@ -1164,7 +1583,12 @@ Function Get-NSXTThingTemplate { if($Thing_id) { $NSXTThings = $NSXTThingsService.get($Thing_id) } else { - $NSXTThings = $NSXTThingsService.list().results + if ($name) { + $NSXTThings = $NSXTThingsService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTThings = $NSXTThingsService.list().results + } } foreach ($NSXTThing in $NSXTThings) { @@ -1180,3 +1604,91 @@ Function Get-NSXTThingTemplate { } } } + +# Set Template +Function Set-NSXTThingTemplate { + <# + .Synopsis + Creates a THING + .DESCRIPTION + Creates a THING with a number of required parameters. + .EXAMPLE + Set-NSXTThingTemplateh -param1 "Name" -param2 "TP Zone ID" + .EXAMPLE + Set-NSXTThingTemplateh -param1 "Name" -param2 "TP Zone ID" +#> + + [CmdletBinding()] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$false)] + [string]$description, + + [parameter(Mandatory=$true)] + [string]$display_name, + + [parameter(Mandatory=$true)] + [string]$transport_zone_id, + + [parameter(Mandatory=$true)] + [ValidateSet("UP","DOWN")] + [string]$admin_state, + + [parameter(Mandatory=$false)] + [ValidateSet("MTEP","SOURCE")] + [string]$replication_mode, + + [parameter(Mandatory=$true)] + [string]$ip_pool_id + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTTHINGService = Get-NsxtService -Name "com.vmware.nsx.THING" + } + + Process + { + $logical_THING_request = $NSXTTHINGService.help.create.logical_switch.Create() + + $logical_THING_request.display_name = $display_name + $logical_THING_request.description = $description + $logical_THING_request.admin_state = $admin_state + $logical_THING_request.transport_zone_id = $transport_zone_id + $logical_THING_request.resource_type = "LogicalSwitch" + $logical_THING_request.replication_mode = $replication_mode + $logical_THING_request.ip_pool_id = $ip_pool_id + + try + { + # + $NSXTTHING = $NSXTTHINGService.create($logical_THING_request) + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + + $NSXTTHING + } +} + + + + From 10f1f26ec16a571473bb8880e7ae7a538cf25835 Mon Sep 17 00:00:00 2001 From: AndyG Date: Fri, 14 Sep 2018 16:16:27 -0400 Subject: [PATCH 29/50] Don't want to export templates Don't want to export templates --- Modules/NSXT/NSXT.psd1 | 2 -- Modules/NSXT/NSXT.psm1 | 2 +- 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/Modules/NSXT/NSXT.psd1 b/Modules/NSXT/NSXT.psd1 index 1ebab1e..537bf49 100644 --- a/Modules/NSXT/NSXT.psd1 +++ b/Modules/NSXT/NSXT.psd1 @@ -22,7 +22,6 @@ 'Get-NSXTManager', 'Get-NSXTNetworkRoutes', 'Get-NSXTRoutingTable', - 'Get-NSXTThingTemplate', 'Get-NSXTTraceFlow', 'Get-NSXTTraceFlowObservations', 'Get-NSXTTransportNode', @@ -30,7 +29,6 @@ 'Set-NSXTIPPool', 'Set-NSXTLogicalRouter', 'Set-NSXTLogicalSwitch', - 'Set-NSXTThingTemplate', 'Set-NSXTTraceFlow' PrivateData = @{ diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index aa30c32..07befe2 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -1452,7 +1452,7 @@ Function Set-NSXTIPPool { .EXAMPLE Set-NSXTIPPool -display_name "Pool Name" -allocation_start "192.168.1.1" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" .EXAMPLE - Set-NSXTIPPool -display_name "Pool Name" -allocation_start "192.168.1.1" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" -dns_nameservers "192.168.1.1" -gateway_ip "192.168.1.1" + Set-NSXTIPPool -display_name "Test Pool Name" -allocation_start "192.168.1.1" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" -dns_nameservers "192.168.1.1" -gateway_ip "192.168.1.1" #> [CmdletBinding()] From 14ecf2107de3bfc728046a86420b6d613a708f87 Mon Sep 17 00:00:00 2001 From: William Lam Date: Sat, 15 Sep 2018 05:32:19 -0700 Subject: [PATCH 30/50] Initial Commit --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 | 88 +++++++++++++ Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 127 +++++++++++++++++++ 2 files changed, 215 insertions(+) create mode 100644 Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 create mode 100644 Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 new file mode 100644 index 0000000..0e68563 --- /dev/null +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 @@ -0,0 +1,88 @@ +# +# Module manifest for module 'VMware.VMC.NSXT' +# +# Generated by: wlam@vmware.com +# +# Generated on: 09/11/18 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'VMware.VMC.NSXT.psm1' + +# Version number of this module. +ModuleVersion = '1.0.0' + +# Supported PSEditions +# CompatiblePSEditions = @() + +# ID used to uniquely identify this module +GUID = 'c094608a-7480-4751-a14c-c9dd68870607' + +# Author of this module +Author = 'William Lam' + +# Company or vendor of this module +CompanyName = 'VMware' + +# Copyright statement for this module +Copyright = '(c) 2018 VMware. All rights reserved.' + +# Description of the functionality provided by this module +Description = 'PowerShell Module for Managing NSX-T on VMware Cloud on AWS' + +# Minimum version of the Windows PowerShell engine required by this module +PowerShellVersion = '6.0' + +# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. +FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment' +# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. +CmdletsToExport = @() + +# Variables to export from this module +VariablesToExport = '*' + +# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. +AliasesToExport = @() + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + # Tags = @() + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + # ProjectUri = '' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + } # End of PSData hashtable + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} \ No newline at end of file diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 new file mode 100644 index 0000000..72f5ebc --- /dev/null +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -0,0 +1,127 @@ +Function Connect-NSXTProxy { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Retrieves NSX-T Proxy URL + acquire CSP Access Token to then be used with NSXT-T Policy API + .DESCRIPTION + This cmdlet creates $global:nsxtProxyConnection object containing the NSX-T Proxy URL along with CSP Token + .EXAMPLE + Connect-NSXTProxy -RefreshToken $RefreshToken -OrgName $OrgName -SDDCName $SDDCName + .NOTES + You must be logged into VMC using Connect-VmcServer cmdlet +#> + Param ( + [Parameter(Mandatory=$true)][String]$RefreshToken, + [Parameter(Mandatory=$true)][String]$OrgName, + [Parameter(Mandatory=$true)][String]$SDDCName + ) + + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; exit } Else { + $sddcService = Get-VmcService "com.vmware.vmc.orgs.sddcs" + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $sddc = $sddcService.get($orgId,$sddcId) + if($sddc.resource_config.nsxt) { + $nsxtProxyURL = $sddc.resource_config.nsx_api_public_endpoint_url + } else { + Write-Host -ForegroundColor Red "This is not an NSX-T based SDDC" + break + } + } + + $results = Invoke-WebRequest -Uri "https://console.cloud.vmware.com/csp/gateway/am/api/auth/api-tokens/authorize?refresh_token=$RefreshToken" -Method POST -ContentType "application/json" -UseBasicParsing -Headers @{"csp-auth-token"="$RefreshToken"} + if($results.StatusCode -ne 200) { + Write-Host -ForegroundColor Red "Failed to retrieve Access Token, please ensure your VMC Refresh Token is valid and try again" + break + } + $accessToken = ($results | ConvertFrom-Json).access_token + + $headers = @{ + "csp-auth-token"="$accessToken" + "Content-Type"="application/json" + "Accept"="application/json" + } + $global:nsxtProxyConnection = new-object PSObject -Property @{ + 'Server' = $nsxtProxyURL + 'headers' = $headers + } + $global:nsxtProxyConnection +} + +Function Get-NSXTSegment { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Segments (Logical Networks) + .DESCRIPTION + This cmdlet retrieves all NSX-T Segments (Logical Networks) + .EXAMPLE + Get-NSXTSegment + .EXAMPLE + Get-NSXTSegment -Name "sddc-cgw-network-1" +#> + Param ( + [Parameter(Mandatory=$False)]$Name, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $segmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/networks/cgw/segments" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$segmentsURL`n" + } + + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $segmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $segmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + + if($requests.StatusCode -eq 200) { + $segments = ($requests.Content | ConvertFrom-Json).results + + if ($PSBoundParameters.ContainsKey("Name")){ + $segments = $segments | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($segment in $segments) { + + $subnets = $segment.subnets + $network = $subnets.network + $gateway = $subnets.gateway_addresses + $dhcpRange = $subnets.dhcp_ranges + + $tmp = [pscustomobject] @{ + Name = $segment.display_name; + ID = $segment.Id; + Network = $network; + Gateway = $gateway; + DHCPRange = $dhcpRange; + } + $results+=$tmp + } + $results + } else { + Write-Error "Failed to retrieve NSX-T Segments" + } + } +} \ No newline at end of file From 9e569b139aeee0a9e994ff1bc07f6e99ef3b16ff Mon Sep 17 00:00:00 2001 From: AndyG Date: Tue, 18 Sep 2018 09:32:36 -0500 Subject: [PATCH 31/50] Added ShouldProcess to Set functions Added ShouldProcess to Set functions --- Modules/NSXT/NSXT.psm1 | 111 ++++++++++++++++++++++++++++++----------- 1 file changed, 83 insertions(+), 28 deletions(-) diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index 07befe2..4616168 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -1121,7 +1121,8 @@ Function Set-NSXTLogicalRouter { Set-NSXTLogicalRouter -display_name "Name" -high_availability_mode "ACTIVE_STANDBY" -router_type "TIER1" -description "this is my new tier1 lr" #> - [CmdletBinding()] + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types Param ( @@ -1191,8 +1192,11 @@ Function Set-NSXTLogicalRouter { try { - # - $NSXTLogicalRouter = $NSXTLogicalRouterService.create($logical_router_request) + # Should process + if ($pscmdlet.ShouldProcess($logical_router_request.display_name, "Create logical router")) + { + $NSXTLogicalRouter = $NSXTLogicalRouterService.create($logical_router_request) + } } catch @@ -1217,7 +1221,8 @@ Function Set-NSXTLogicalSwitch { Set-NSXTLogicalSwitch -display_name "Name" -transport_zone_id "TP Zone ID" -admin_state "UP" -replication_mode "MTEP" -ip_pool_id "IP Pool Name" #> - [CmdletBinding()] + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types Param ( @@ -1274,8 +1279,12 @@ Function Set-NSXTLogicalSwitch { try { - # - $NSXTLogicalSwitch = $NSXTLogicalSwitchService.create($logical_switch_request) + # Should process + if ($pscmdlet.ShouldProcess($logical_switch_request.display_name, "Create logical switch")) + { + $NSXTLogicalSwitch = $NSXTLogicalSwitchService.create($logical_switch_request) + } + } catch @@ -1303,7 +1312,8 @@ Function Set-NSXTTraceFlow { Set-NSXTTraceFlow -transport_type "UNICAST" -lport_id "LP ID" -src_ip "IP Address" -src_mac "MAC" -dst_ip "IP Address" -dst_mac "MAC" | Get-NSXTTraceFlow | Get-NSXTTraceFlowObservations #> - [CmdletBinding()] + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types Param ( @@ -1429,8 +1439,12 @@ Function Set-NSXTTraceFlow { try { - # This does not work, bug report submitted to PowerCLI team - $NSXTraceFlow = $NSXTraceFlowService.create($traceflow_request) + # Should process + if ($pscmdlet.ShouldProcess($traceflow_request.lport_id, "Create traceflow")) + { + # This does not work, bug report submitted to PowerCLI team + $NSXTraceFlow = $NSXTraceFlowService.create($traceflow_request) + } } catch @@ -1455,7 +1469,8 @@ Function Set-NSXTIPPool { Set-NSXTIPPool -display_name "Test Pool Name" -allocation_start "192.168.1.1" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" -dns_nameservers "192.168.1.1" -gateway_ip "192.168.1.1" #> - [CmdletBinding()] + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types Param ( @@ -1497,29 +1512,65 @@ Function Set-NSXTIPPool { } $NSXTIPPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools" + + class allocation_ranges { + [string]$start + [string]$end + $self + } + + class subnets { + [string]$dns_nameservers + [string]$dns_suffix + [string]$cidr + [string]$gateway_ip + $allocation_ranges = [allocation_ranges]::new() + hidden $self + + } + + class ip_pool { + [string]$display_name + [string]$description + [string]$resource_type = 'IpPool' + [long]$revision = '0' + #$subnets = [subnets]::new() + $subnets = [System.Collections.Generic.List[subnets]]::new() + hidden $pool_usage + hidden $tags + hidden $self + hidden $links = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + } + } Process { - $ip_pool_request = $NSXTIPPoolService.help.create.ip_pool.Create() - $ip_pool_request.subnets = $NSXTIPPoolService.help.create.ip_pool.subnets.Create() - $ip_pool_request.subnets = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.Create() - $ip_pool_request.subnets.allocation_ranges = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.create() - $ip_pool_request.subnets.allocation_ranges = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.element.create() + $ip_pool = [ip_pool]::new() + $ip_pool = $NSXTIPPoolService.help.create.ip_pool.Create() + $ip_pool.subnets = $NSXTIPPoolService.help.create.ip_pool.subnets.Create() + $ip_pool.subnets = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.Create() + $ip_pool.subnets.allocation_ranges = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.create() + $ip_pool.subnets.allocation_ranges = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.element.create() + #$ip_pool = [ip_pool]::new() - $ip_pool_request.display_name = $display_name - $ip_pool_request.description = $description - $ip_pool_request.resource_type = "IpPool" - $ip_pool_request.subnets.dns_nameservers = $dns_nameservers - $ip_pool_request.subnets.allocation_ranges.start = $allocation_start - $ip_pool_request.subnets.allocation_ranges.end = $allocation_end - $ip_pool_request.subnets.cidr = $cidr - $ip_pool_request.subnets.gateway_ip = $gateway_ip + $ip_pool.display_name = $display_name + $ip_pool.description = $description + $ip_pool.resource_type = "IpPool" + $ip_pool.subnets.dns_nameservers = $dns_nameservers + $ip_pool.subnets.allocation_ranges.start = $allocation_start + $ip_pool.subnets.allocation_ranges.end = $allocation_end + $ip_pool.subnets.cidr = $cidr + $ip_pool.subnets.gateway_ip = $gateway_ip + $ip_pool.revision = 0 try { - # - $NSXTIPPool = $NSXTIPPoolService.create($ip_pool_request) + # Should process + if ($pscmdlet.ShouldProcess($ip_pool.display_name, "Create IP Pool")) + { + $NSXTIPPool = $NSXTIPPoolService.create($ip_pool) + } } catch @@ -1618,7 +1669,8 @@ Function Set-NSXTThingTemplate { Set-NSXTThingTemplateh -param1 "Name" -param2 "TP Zone ID" #> - [CmdletBinding()] + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types Param ( @@ -1675,8 +1727,11 @@ Function Set-NSXTThingTemplate { try { - # - $NSXTTHING = $NSXTTHINGService.create($logical_THING_request) + # Should process + if ($pscmdlet.ShouldProcess($ip_pool.display_name, "Create IP Pool")) + { + $NSXTTHING = $NSXTTHINGService.create($logical_THING_request) + } } catch From e8b64517c7b6a5121eba2c0725db3149e7da9010 Mon Sep 17 00:00:00 2001 From: AndyG Date: Tue, 18 Sep 2018 16:45:59 -0500 Subject: [PATCH 32/50] Added Get/Set/Remove IPAMIPBlock Added Get/Set/Remove IPAMIPBlock --- Modules/NSXT/NSXT.psd1 | 5 +- Modules/NSXT/NSXT.psm1 | 281 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 278 insertions(+), 8 deletions(-) diff --git a/Modules/NSXT/NSXT.psd1 b/Modules/NSXT/NSXT.psd1 index 537bf49..83026e8 100644 --- a/Modules/NSXT/NSXT.psd1 +++ b/Modules/NSXT/NSXT.psd1 @@ -29,7 +29,10 @@ 'Set-NSXTIPPool', 'Set-NSXTLogicalRouter', 'Set-NSXTLogicalSwitch', - 'Set-NSXTTraceFlow' + 'Set-NSXTTraceFlow', + 'Get-NSXTIPAMIPBlock', + 'Set-NSXTIPAMIPBlock', + 'Remove-NSXTIPAMIPBlock' PrivateData = @{ PSData = @{ diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index 4616168..3d6a4f7 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -1106,6 +1106,72 @@ Function Get-NSXTIPPool { } } +Function Get-NSXTIPAMIPBlock { + <# + .Synopsis + Retrieves the IPAM IP Block information + .DESCRIPTION + Retrieves IPAM IP Block information for a single or multiple ports. Execute with no parameters to get all ports, specify a PARAM if known. + .EXAMPLE + Get-NSXTIPAMIPBlock + .EXAMPLE + Get-NSXTIPAMIPBlock -block_id "Block Id" + .EXAMPLE + Get-NSXTIPAMIPBlock -name "Block Name" + +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$block_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTIPAMIPBlocksService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_blocks" + + class ip_block { + [string]$Name + [string]$block_id + hidden [string]$Tags = [System.Collections.Generic.List[string]]::new() + [string]$protection + #[ValidateSet("TIER0","TIER1")] + [string]$cidr + hidden [string]$resource_type + } + } + + Process + { + if($block_id) { + $NSXTIPAMIPBlocks = $NSXTIPAMIPBlocksService.get($block_id) + } else { + if ($name) { + $NSXTIPAMIPBlocks = $NSXTIPAMIPBlocksService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTIPAMIPBlocks = $NSXTIPAMIPBlocksService.list().results + } + } + + foreach ($NSXTIPAMIPBlock in $NSXTIPAMIPBlocks) { + + $results = [ip_block]::new() + $results.Name = $NSXTIPAMIPBlock.display_name; + $results.block_id = $NSXTIPAMIPBlock.id; + $results.Tags = $NSXTIPAMIPBlock.tags; + $results.protection = $NSXTIPAMIPBlock.protection; + $results.cidr = $NSXTIPAMIPBlock.cidr; + $results.resource_type = $NSXTIPAMIPBlock.resource_type + + $results + } + } +} + # Working Set Functions Function Set-NSXTLogicalRouter { <# @@ -1297,6 +1363,140 @@ Function Set-NSXTLogicalSwitch { } } +Function Set-NSXTIPAMIPBlock { + <# + .Synopsis + Creates an IPAM IP Block + .DESCRIPTION + Creates a IPAM IP Block with a cidr parameter. + .EXAMPLE + Set-NSXTIPAMIPBlock -name "IPAM Block Name" -cidr "192.168.0.0/24" +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='Medium')] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$false)] + [string]$description, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$display_name, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$cidr + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTIPAMIPBlockService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_blocks" + } + + Process + { + $IPAMIPBlock_request = $NSXTIPAMIPBlockService.help.create.ip_block.Create() + + $IPAMIPBlock_request.display_name = $display_name + $IPAMIPBlock_request.description = $description + $IPAMIPBlock_request.resource_type = "IpBlock" + $IPAMIPBlock_request.cidr = $cidr + + + try + { + # Should process + if ($pscmdlet.ShouldProcess($ip_pool.display_name, "Create IP Pool")) + { + $NSXTIPAMIPBlock = $NSXTIPAMIPBlockService.create($IPAMIPBlock_request) + } + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + + $NSXTIPAMIPBlock + } +} + +# Remove functions +Function Remove-NSXTIPAMIPBlock { + <# + .Synopsis + Removes an IPAM IP Block + .DESCRIPTION + Removes a IPAM IP Block with a block_id parameter. + .EXAMPLE + Remove-NSXTIPAMIPBlock -block_id "id" + .EXAMPLE + Get-NSXTIPAMIPBlock | where name -eq "IPAM Test2" | Remove-NSXTIPAMIPBlock +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='High')] + + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [ValidateNotNullOrEmpty()] + [Alias("Id")] + [string]$block_id + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTIPAMIPBlockService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_blocks" + } + + Process + { + try + { + # Should process + if ($pscmdlet.ShouldProcess($block_id, "Delete IP Pool")) + { + $NSXTIPAMIPBlockService.delete($block_id) + } + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + } +} + # Non-working Set Functions Function Set-NSXTTraceFlow { <# @@ -1475,6 +1675,7 @@ Function Set-NSXTIPPool { # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types Param ( [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string]$display_name, [parameter(Mandatory=$false)] @@ -1484,12 +1685,15 @@ Function Set-NSXTIPPool { [string]$dns_nameservers, [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string]$allocation_start, [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string]$allocation_end, [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string]$cidr, [parameter(Mandatory=$false)] @@ -1534,25 +1738,22 @@ Function Set-NSXTIPPool { [string]$description [string]$resource_type = 'IpPool' [long]$revision = '0' - #$subnets = [subnets]::new() - $subnets = [System.Collections.Generic.List[subnets]]::new() + $subnets = [subnets]::new() hidden $pool_usage hidden $tags hidden $self - hidden $links = [System.Collections.Generic.List[System.Management.Automation.PSObject]]::new() + hidden $links = [System.Collections.Generic.List[string]]::new() } } Process { - $ip_pool = [ip_pool]::new() $ip_pool = $NSXTIPPoolService.help.create.ip_pool.Create() $ip_pool.subnets = $NSXTIPPoolService.help.create.ip_pool.subnets.Create() $ip_pool.subnets = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.Create() $ip_pool.subnets.allocation_ranges = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.create() $ip_pool.subnets.allocation_ranges = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.element.create() - #$ip_pool = [ip_pool]::new() $ip_pool.display_name = $display_name $ip_pool.description = $description @@ -1563,6 +1764,9 @@ Function Set-NSXTIPPool { $ip_pool.subnets.cidr = $cidr $ip_pool.subnets.gateway_ip = $gateway_ip $ip_pool.revision = 0 + + # Accepted JSON object ok yet it did not interpret any of the parameters + #$ip_pool_json = ConvertTo-Json $ip_pool try { @@ -1576,7 +1780,7 @@ Function Set-NSXTIPPool { catch { $Error[0].Exception.ServerError.data - # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file; grep POOL-MGMT throw } @@ -1584,6 +1788,8 @@ Function Set-NSXTIPPool { } } +########################### + # Get Template Function Get-NSXTThingTemplate { <# @@ -1678,9 +1884,11 @@ Function Set-NSXTThingTemplate { [string]$description, [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string]$display_name, [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string]$transport_zone_id, [parameter(Mandatory=$true)] @@ -1692,6 +1900,7 @@ Function Set-NSXTThingTemplate { [string]$replication_mode, [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] [string]$ip_pool_id ) @@ -1744,6 +1953,64 @@ Function Set-NSXTThingTemplate { } } - +# Remove Template +Function Remove-NSXTThingTemplate { + <# + .Synopsis + Removes an IPAM IP Block + .DESCRIPTION + Removes a IPAM IP Block with a block_id parameter. + .EXAMPLE + Remove-NSXTIPAMIPBlock -block_id "id" +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='High')] + + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [ValidateNotNullOrEmpty()] + [Alias("Id")] + [string]$thing_id + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTTHINGkService = Get-NsxtService -Name "com.vmware.nsx.THING" + } + + Process + { + try + { + # Should process + if ($pscmdlet.ShouldProcess($thing_id, "Delete IP Pool")) + { + $NSXTTHINGkService.delete($thing_id) + } + } + + catch + { + throw $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file. + } + } +} + +$NSXTIPSubnetsService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_subnets" From 526f6a8ad902d99e334ccb869372d8475bf79f4c Mon Sep 17 00:00:00 2001 From: William Lam Date: Tue, 18 Sep 2018 14:47:36 -0700 Subject: [PATCH 33/50] Check $global:DefaultVMCServers.IsConnected during NSX-T Proxy Connect --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index 72f5ebc..126cad5 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -24,7 +24,7 @@ Function Connect-NSXTProxy { [Parameter(Mandatory=$true)][String]$SDDCName ) - If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; exit } Else { + If (-Not $global:DefaultVMCServers.IsConnected) { Write-error "No valid VMC Connection found, please use the Connect-VMC to connect"; break } Else { $sddcService = Get-VmcService "com.vmware.vmc.orgs.sddcs" $orgId = (Get-VMCOrg -Name $OrgName).Id $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id From 16b32f1b03dd96c96a7091d7cb104a2355f4272b Mon Sep 17 00:00:00 2001 From: William Lam Date: Wed, 19 Sep 2018 05:34:20 -0700 Subject: [PATCH 34/50] Additional NSX-T Policy API functions --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 | 2 +- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 766 ++++++++++++++++++- 2 files changed, 762 insertions(+), 6 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 index 0e68563..c7feb19 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 @@ -36,7 +36,7 @@ Description = 'PowerShell Module for Managing NSX-T on VMware Cloud on AWS' PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment' +FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index 126cad5..09b6b4d 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -81,7 +81,7 @@ Function Get-NSXTSegment { [Switch]$Troubleshoot ) - If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { $method = "GET" $segmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/networks/cgw/segments" @@ -89,10 +89,15 @@ Function Get-NSXTSegment { Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$segmentsURL`n" } - if($PSVersionTable.PSEdition -eq "Core") { - $requests = Invoke-WebRequest -Uri $segmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck - } else { - $requests = Invoke-WebRequest -Uri $segmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $segmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $segmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break } if($requests.StatusCode -eq 200) { @@ -124,4 +129,755 @@ Function Get-NSXTSegment { Write-Error "Failed to retrieve NSX-T Segments" } } +} + +Function New-NSXTSegment { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Creates a new NSX-T Segment (Logical Networks) + .DESCRIPTION + This cmdlet creates a new NSX-T Segment (Logical Networks) + .EXAMPLE + New-NSXTSegment -Name "sddc-cgw-network-4" -Gateway "192.168.4.1" -Prefix "24" -DHCP -DHCPRange "192.168.4.2-192.168.4.254" +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Parameter(Mandatory=$True)]$Gateway, + [Parameter(Mandatory=$True)]$Prefix, + [Parameter(Mandatory=$False)]$DHCPRange, + [Switch]$DHCP, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + if($DHCP) { + $dhcpConf = @($DHCPRange) + } else { + $dhcpConf = @($null) + } + + $subnets = @{ + gateway_addresses = @($gateway); + prefix_len = $Prefix; + dhcp_ranges = $dhcpConf + } + + $payload = @{ + display_name = $Name; + subnets = @($subnets) + } + $body = $payload | ConvertTo-Json -depth 4 + + $method = "PUT" + $newSegmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/networks/cgw/segments/$Name" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$newSegmentsURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $newSegmentsURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $newSegmentsURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully created new NSX-T Segment $Name" + ($requests.Content | ConvertFrom-Json) | select display_name, id + } else { + Write-Error "Failed to create new NSX-T Segment" + + } + } +} + +Function Remove-NSXTSegment { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes an NSX-T Segment (Logical Networks) + .DESCRIPTION + This cmdlet removes an NSX-T Segment (Logical Networks) + .EXAMPLE + Remove-NSXTSegment -Id "sddc-cgw-network-4" +#> + Param ( + [Parameter(Mandatory=$True)]$Id, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "DELETE" + $deleteSegmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/networks/cgw/segments/$Id" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteSegmentsURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteSegmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteSegmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully removed NSX-T Segment $Name" + } else { + Write-Error "Failed to remove NSX-T Segments" + + } + } +} + +Function Get-NSXTFirewall { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Firewall Rules on MGW or CGW + .DESCRIPTION + This cmdlet retrieves all NSX-T Firewall Rules on MGW or CGW + .EXAMPLE + Get-NSXTFirewall -GatewayType MGW + .EXAMPLE + Get-NSXTFirewall -GatewayType MGW -Name "Test" +#> + param( + [Parameter(Mandatory=$false)][String]$Name, + [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $edgeFirewallURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/edge-communication-maps/default" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$edgeFirewallURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $edgeFirewallURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $edgeFirewallURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + + if($requests.StatusCode -eq 200) { + $rules = ($requests.Content | ConvertFrom-Json).communication_entries + + if ($PSBoundParameters.ContainsKey("Name")){ + $rules = $rules | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($rule in $rules | Sort-Object -Property sequence_number) { + $sourceGroups = $rule.source_groups + $source = @() + foreach ($sourceGroup in $sourceGroups) { + if($sourceGroup -eq "ANY") { + $source += $sourceGroup + break + } else { + $sourceGroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1" + $sourceGroup + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$sourceGroupURL`n" + } + try { + $requests = Invoke-WebRequest -Uri $sourceGroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + $group = ($requests.Content | ConvertFrom-Json) + $source += $group.display_name + } + } + + $destinationGroups = $rule.destination_groups + $destination = @() + foreach ($destinationGroup in $destinationGroups) { + if($destinationGroup -eq "ANY") { + $destination += $destinationGroup + break + } else { + $destionationGroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1" + $destinationGroup + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$destionationGroupURL`n" + } + try { + $requests = Invoke-WebRequest -Uri $destionationGroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + $group = ($requests.Content | ConvertFrom-Json) + $destination += $group.display_name + } + } + + $serviceGroups = $rule.services + $service = @() + foreach ($serviceGroup in $serviceGroups) { + if($serviceGroup -eq "ANY") { + $service += $serviceGroup + break + } else { + $serviceGroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1" + $serviceGroup + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$serviceGroupURL`n" + } + try { + $requests = Invoke-WebRequest -Uri $serviceGroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + $group = ($requests.Content | ConvertFrom-Json) + $service += $group.display_name + } + } + + $tmp = [pscustomobject] @{ + SequenceNumber = $rule.sequence_number; + Name = $rule.display_name; + ID = $rule.id; + Source = $source; + Destination = $destination; + Services = $service; + Action = $rule.action; + } + $results+=$tmp + } + $results + + } else { + Write-Error "Failed to retrieve NSX-T Firewall Rules" + } + } +} + +Function New-NSXTFirewall { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Creates a new NSX-T Firewall Rule on MGW or CGW + .DESCRIPTION + This cmdlet creates a new NSX-T Firewall Rule on MGW or CGW + .EXAMPLE + New-NSXTFirewall -GatewayType MGW -Name TEST -Id TEST -SourceGroupId ESXI -DestinationGroupId ANY -Service ANY -Logged $true -SequenceNumber 7 -Action ALLOW +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, + [Parameter(Mandatory=$True)]$Id, + [Parameter(Mandatory=$True)]$SequenceNumber, + [Parameter(Mandatory=$True)]$SourceGroupId, + [Parameter(Mandatory=$True)]$DestinationGroupId, + [Parameter(Mandatory=$True)]$Service, + [Parameter(Mandatory=$True)][ValidateSet("ALLOW","DENY")]$Action, + [Parameter(Mandatory=$false)][Boolean]$Logged=$false, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + + if($DestinationGroupId -eq "ANY") { + $destinationGroups = $DestinationGroupId + } else { + $destinationGroups = "/infra/domains/$($GatewayType.toLower())/groups/$DestinationGroupId" + } + + $sourceGroups = @() + foreach ($group in $SourceGroupId) { + $tmp = "/infra/domains/$($GatewayType.toLower())/groups/$group" + $sourceGroups+= $tmp + } + + $services = @() + foreach ($serviceName in $Service) { + if($serviceName -eq "ANY") { + $tmp = "ANY" + } else { + $tmp = "/infra/services/$serviceName" + } + $services+=$tmp + } + + $payload = @{ + display_name = $Name; + resource_type = "CommunicationEntry"; + id = $Id; + sequence_number = $SequenceNumber; + destination_groups = @($destinationGroups); + source_groups = $sourceGroups; + logged = $Logged; + scope = @("/infra/labels/$($GatewayType.toLower())"); + services = $services; + action = $Action; + } + + $body = $payload | ConvertTo-Json -depth 5 + + $method = "PUT" + $newFirewallURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/edge-communication-maps/default/communication-entries/$Id" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$newFirewallURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $newFirewallURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $newFirewallURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully created new NSX-T Firewall Rule $Name" + ($requests.Content | ConvertFrom-Json) | select display_name, id + } else { + Write-Error "Failed to create new NSX-T Firewall Rule" + } + } +} + +Function Remove-NSXTFirewall { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes an NSX-T Firewall Rule on MGW or CGW + .DESCRIPTION + This cmdlet removes an NSX-T Firewall Rule on MGW or CGW + .EXAMPLE + Remove-NSXTFirewall -Id TEST -GatewayType MGW -Troubleshoot +#> + Param ( + [Parameter(Mandatory=$True)]$Id, + [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "DELETE" + $deleteGgroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/edge-communication-maps/default/communication-entries/$Id" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteGgroupURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteGgroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteGgroupURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully removed NSX-T Firewall Rule $Name" + } else { + Write-Error "Failed to create new NSX-T Firewall Rule" + } + } +} + +Function Get-NSXTGroup { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Groups for MGW or CGW + .DESCRIPTION + This cmdlet retrieves all NSX-T Groups for MGW or CGW + .EXAMPLE + Get-NSXTGroup -GatewayType MGW + .EXAMPLE + Get-NSXTGroup -GatewayType MGW -Name "Test" +#> + param( + [Parameter(Mandatory=$false)][String]$Name, + [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $edgeFirewallGroupsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/groups" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$edgeFirewallGroupsURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $edgeFirewallGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $edgeFirewallGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + + if($requests.StatusCode -eq 200) { + $groups = ($requests.Content | ConvertFrom-Json).results + + if ($PSBoundParameters.ContainsKey("Name")){ + $groups = $groups | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($group in $groups) { + if($group.tags.tag -eq $null) { + $groupType = "USER_DEFINED" + } else { $groupType = $group.tags.tag } + + $members = @() + foreach ($member in $group.expression) { + $members += $member.ip_addresses + } + + $tmp = [pscustomobject] @{ + Name = $group.display_name; + ID = $group.id; + Type = $groupType; + Members = $members; + } + $results+=$tmp + } + $results + } else { + Write-Error "Failed to retrieve NSX-T Groups" + } + } +} + +Function New-NSXTGroup { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Creates a new NSX-T Group on MGW or CGW + .DESCRIPTION + This cmdlet creates a new NSX-T Firewall Rule on MGW or CGW + .EXAMPLE + New-NSXTGroup -GatewayType MGW -Name Foo -IPAddress @("172.31.0.0/24") +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, + [Parameter(Mandatory=$True)][String[]]$IPAddress, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $expression = @{ + resource_type = "IPAddressExpression"; + ip_addresses = $IPAddress; + } + + $payload = @{ + display_name = $Name; + expression = @($expression); + } + $body = $payload | ConvertTo-Json -depth 5 + + $method = "PUT" + $newGroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/groups/$Name" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$newGroupURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $newGroupURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $newGroupURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully created new NSX-T Group $Name" + ($requests.Content | ConvertFrom-Json) | select display_name, id + } else { + Write-Error "Failed to create new NSX-T Group" + } + } +} + +Function Remove-NSXTGROUP { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Removes an NSX-T Group + .DESCRIPTION + This cmdlet removes an NSX-T Group + .EXAMPLE + Remove-NSXTGROUP -Id Foo -GatewayType MGW -Troubleshoot +#> + Param ( + [Parameter(Mandatory=$True)]$Id, + [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "DELETE" + $deleteGgroupURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/domains/$($GatewayType.toLower())/groups/$Id" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$deleteGgroupURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $deleteGgroupURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $deleteGgroupURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully removed NSX-T Group $Name" + } else { + Write-Error "Failed to create new NSX-T Group" + } + } +} + +Function Get-NSXTService { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns all NSX-T Services + .DESCRIPTION + This cmdlet retrieves all NSX-T Services + .EXAMPLE + Get-NSXTService + .EXAMPLE + Get-NSXTService -Name "WINS" +#> + param( + [Parameter(Mandatory=$false)][String]$Name, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $method = "GET" + $serviceGroupsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/services" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$serviceGroupsURL`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $serviceGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $serviceGroupsURL -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + + if($requests.StatusCode -eq 200) { + $services = ($requests.Content | ConvertFrom-Json).results + + if ($PSBoundParameters.ContainsKey("Name")){ + $services = $services | where {$_.display_name -eq $Name} + } + + $results = @() + foreach ($service in $services | Sort-Object -Propert display_name) { + $serviceEntry = $service.service_entries + $serviceProtocol = $serviceEntry.l4_protocol + $serviceSourcePorts = $serviceEntry.source_ports + $serviceDestinationPorts = $serviceEntry.destination_ports + + $tmp = [pscustomobject] @{ + Name = $service.display_name; + Id = $service.id; + Protocol = $serviceProtocol; + Source = $serviceSourcePorts; + Destination = $serviceDestinationPorts; + } + $results += $tmp + } + $results + } else { + Write-Error "Failed to retrieve NSX-T Services" + } + } +} + +Function New-NSXTService { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/11/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Creates a new NSX-T Service + .DESCRIPTION + This cmdlet creates a new NSX-T Service + .EXAMPLE + New-NSXTService -Name "MyHTTP2" -Protocol TCP -DestinationPorts @("8080","8081") +#> + Param ( + [Parameter(Mandatory=$True)]$Name, + [Parameter(Mandatory=$True)][String[]]$DestinationPorts, + [Parameter(Mandatory=$True)][ValidateSet("TCP","UDP")][String]$Protocol, + [Switch]$Troubleshoot + ) + + If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else { + $serviceEntry = @() + $entry = @{ + display_name = $name + "-$destinationPort" + resource_type = "L4PortSetServiceEntry"; + destination_ports = @($DestinationPorts); + l4_protocol = $Protocol; + } + $serviceEntry+=$entry + + $payload = @{ + display_name = $Name; + service_entries = $serviceEntry; + } + $body = $payload | ConvertTo-Json -depth 5 + + $method = "PUT" + $newServiceURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/services/$Name" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$newServiceURL`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $newServiceURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $newServiceURL -Body $body -Method $method -Headers $global:nsxtProxyConnection.headers + } + } catch { + Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n" + break + } + + if($requests.StatusCode -eq 200) { + Write-Host "Succesfully created new NSX-T Service $Name" + ($requests.Content | ConvertFrom-Json) | select display_name, id + } else { + Write-Error "Failed to create new NSX-T Service" + } + } } \ No newline at end of file From 691709dd40d1f8b0c33bd78adcd6d6d9618f7732 Mon Sep 17 00:00:00 2001 From: William Lam Date: Wed, 19 Sep 2018 05:34:54 -0700 Subject: [PATCH 35/50] Initial commit for HCX PowerShell Module --- Modules/VMware.HCX/VMware.HCX.psd1 | 88 +++++++++++++++ Modules/VMware.HCX/VMware.HCX.psm1 | 176 +++++++++++++++++++++++++++++ 2 files changed, 264 insertions(+) create mode 100644 Modules/VMware.HCX/VMware.HCX.psd1 create mode 100644 Modules/VMware.HCX/VMware.HCX.psm1 diff --git a/Modules/VMware.HCX/VMware.HCX.psd1 b/Modules/VMware.HCX/VMware.HCX.psd1 new file mode 100644 index 0000000..de1f200 --- /dev/null +++ b/Modules/VMware.HCX/VMware.HCX.psd1 @@ -0,0 +1,88 @@ +# +# Module manifest for module 'VMware.HCX' +# +# Generated by: wlam@vmware.com +# +# Generated on: 09/11/18 +# + +@{ + +# Script module or binary module file associated with this manifest. +RootModule = 'VMware.HCX.psm1' + +# Version number of this module. +ModuleVersion = '1.0.0' + +# Supported PSEditions +# CompatiblePSEditions = @() + +# ID used to uniquely identify this module +GUID = '88898ed6-26e8-4dfa-a9de-10d3a12571de' + +# Author of this module +Author = 'William Lam' + +# Company or vendor of this module +CompanyName = 'VMware' + +# Copyright statement for this module +Copyright = '(c) 2018 VMware. All rights reserved.' + +# Description of the functionality provided by this module +Description = 'PowerShell Module for Managing Hybrid Cloud Extension (HCX) on VMware Cloud on AWS' + +# Minimum version of the Windows PowerShell engine required by this module +PowerShellVersion = '6.0' + +# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. +FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Connect-HcxVAMI', 'Get-HcxVAMIVCConfig' +# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. +CmdletsToExport = @() + +# Variables to export from this module +VariablesToExport = '*' + +# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export. +AliasesToExport = @() + +# DSC resources to export from this module +# DscResourcesToExport = @() + +# List of all modules packaged with this module +# ModuleList = @() + +# List of all files packaged with this module +# FileList = @() + +# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell. +PrivateData = @{ + + PSData = @{ + + # Tags applied to this module. These help with module discovery in online galleries. + # Tags = @() + + # A URL to the license for this module. + # LicenseUri = '' + + # A URL to the main website for this project. + # ProjectUri = '' + + # A URL to an icon representing this module. + # IconUri = '' + + # ReleaseNotes of this module + # ReleaseNotes = '' + + } # End of PSData hashtable + +} # End of PrivateData hashtable + +# HelpInfo URI of this module +# HelpInfoURI = '' + +# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix. +# DefaultCommandPrefix = '' + +} \ No newline at end of file diff --git a/Modules/VMware.HCX/VMware.HCX.psm1 b/Modules/VMware.HCX/VMware.HCX.psm1 new file mode 100644 index 0000000..222f8d1 --- /dev/null +++ b/Modules/VMware.HCX/VMware.HCX.psm1 @@ -0,0 +1,176 @@ +Function Connect-HcxServer { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Connect to the HCX Enterprise Manager + .DESCRIPTION + This cmdlet connects to the HCX Enterprise Manager + .EXAMPLE + Connect-HcxServer -Server $HCXServer -Username $Username -Password $Password +#> + Param ( + [Parameter(Mandatory=$true)][String]$Server, + [Parameter(Mandatory=$true)][String]$Username, + [Parameter(Mandatory=$true)][String]$Password + ) + + $payload = @{ + "username" = $Username + "password" = $Password + } + $body = $payload | ConvertTo-Json + + $hcxLoginUrl = "https://$Server/hybridity/api/sessions" + + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $hcxLoginUrl -Body $body -Method POST -UseBasicParsing -ContentType "application/json" -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $hcxLoginUrl -Body $body -Method POST -UseBasicParsing -ContentType "application/json" + } + + if($results.StatusCode -eq 200) { + $hcxAuthToken = $results.Headers.'x-hm-authorization' + + $headers = @{ + "x-hm-authorization"="$hcxAuthToken" + "Content-Type"="application/json" + "Accept"="application/json" + } + + $global:hcxConnection = new-object PSObject -Property @{ + 'Server' = "https://$server/hybridity/api"; + 'headers' = $headers + } + $global:hcxConnection + } else { + Write-Error "Failed to connect to HCX Manager, please verify your vSphere SSO credentials" + } +} + +Function Get-HcxCloudConfig { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the Cloud HCX information that is registerd with HCX Manager + .DESCRIPTION + This cmdlet returns the Cloud HCX information that is registerd with HCX Manager + .EXAMPLE + Get-HcxCloudConfig +#> + If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxServer " } Else { + $cloudConfigUrl = $global:hcxConnection.Server + "/cloudConfigs" + + if($PSVersionTable.PSEdition -eq "Core") { + $cloudvcRequests = Invoke-WebRequest -Uri $cloudConfigUrl -Method GET -Headers $global:hcxConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $cloudvcRequests = Invoke-WebRequest -Uri $cloudConfigUrl -Method GET -Headers $global:hcxConnection.headers -UseBasicParsing + } + + $cloudvcData = ($cloudvcRequests.content | ConvertFrom-Json).data.items + + $tmp = [pscustomobject] @{ + Name = $cloudvcData.cloudName; + Version = $cloudvcData.version; + Build = $cloudvcData.buildNumber; + HCXUUID = $cloudvcData.endpointId; + } + $tmp + } +} + +Function Connect-HcxVAMI { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Connect to the HCX Enterprise Manager VAMI + .DESCRIPTION + This cmdlet connects to the HCX Enterprise Manager VAMI + .EXAMPLE + Connect-HcxVAMI -Server $HCXServer -Username $VAMIUsername -Password $VAMIPassword +#> + Param ( + [Parameter(Mandatory=$true)][String]$Server, + [Parameter(Mandatory=$true)][String]$Username, + [Parameter(Mandatory=$true)][String]$Password + ) + + $pair = "${Username}:${Password}" + $bytes = [System.Text.Encoding]::ASCII.GetBytes($pair) + $base64 = [System.Convert]::ToBase64String($bytes) + $basicAuthValue = "Basic $base64" + + $headers = @{ + "authorization"="$basicAuthValue" + "Content-Type"="application/json" + "Accept"="application/json" + } + + $global:hcxVAMIConnection = new-object PSObject -Property @{ + 'Server' = "https://${server}:9443"; + 'headers' = $headers + } + $global:hcxVAMIConnection +} + +Function Get-HcxVAMIVCConfig { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the onPrem vCenter Server registered with HCX Manager + .DESCRIPTION + This cmdlet returns the onPrem vCenter Server registered with HCX Manager + .EXAMPLE + Get-HcxVAMIVCConfig +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $vcConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/vcenter" + + if($PSVersionTable.PSEdition -eq "Core") { + $vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $vcRequests = Invoke-WebRequest -Uri $vcConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + $vcData = ($vcRequests.content | ConvertFrom-Json).data.items + + $tmp = [pscustomobject] @{ + Name = $vcData.config.name; + Version = $vcData.config.version; + Build = $vcData.config.buildNumber; + UUID = $vcData.config.vcuuid; + HCXUUID = $vcData.config.uuid; + } + $tmp + } +} \ No newline at end of file From 39c179ae1a2b114d81545bb15794f09824812d2a Mon Sep 17 00:00:00 2001 From: AndyG Date: Wed, 19 Sep 2018 15:01:25 -0500 Subject: [PATCH 36/50] Added Get-NSXTClusterNode Added Get-NSXTClusterNode --- Modules/NSXT/NSXT.psd1 | 2 + Modules/NSXT/NSXT.psm1 | 160 ++++++++++++++++++++++++++++++++--------- 2 files changed, 129 insertions(+), 33 deletions(-) diff --git a/Modules/NSXT/NSXT.psd1 b/Modules/NSXT/NSXT.psd1 index 83026e8..3cee460 100644 --- a/Modules/NSXT/NSXT.psd1 +++ b/Modules/NSXT/NSXT.psd1 @@ -26,6 +26,7 @@ 'Get-NSXTTraceFlowObservations', 'Get-NSXTTransportNode', 'Get-NSXTTransportZone', + 'Get-NSXTClusterNode', 'Set-NSXTIPPool', 'Set-NSXTLogicalRouter', 'Set-NSXTLogicalSwitch', @@ -33,6 +34,7 @@ 'Get-NSXTIPAMIPBlock', 'Set-NSXTIPAMIPBlock', 'Remove-NSXTIPAMIPBlock' + PrivateData = @{ PSData = @{ diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index 3d6a4f7..99e149b 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -1172,6 +1172,84 @@ Function Get-NSXTIPAMIPBlock { } } +Function Get-NSXTClusterNode { + <# + .Synopsis + Retrieves the cluster node information + .DESCRIPTION + Retrieves cluster node information including manager and controller nodes. + .EXAMPLE + Get-NSXTClusterNode + .EXAMPLE + Get-NSXTClusterNode -node_id "Node Id" + .EXAMPLE + Get-NSXTClusterNode -name "Name" +#> + + Param ( + [parameter(Mandatory=$false,ValueFromPipelineByPropertyName=$true)] + [Alias("Id")] + [string]$node_id, + [parameter(Mandatory=$false)] + [string]$name + ) + + begin + { + $NSXTClusterNodesService = Get-NsxtService -Name "com.vmware.nsx.cluster.nodes" + + class NSXTClusterNode { + [string]$Name + [string]$node_id + hidden [array]$Tags = [System.Collections.Generic.List[string]]::new() + hidden [string]$controller_role + hidden [array]$manager_role + [string]$protection + [string]$appliance_mgmt_listen_addr + hidden [string]$external_id + hidden [string]$description + [string]$role + } + } + + Process + { + if($node_id) { + $NSXTThings = $NSXTClusterNodesService.get($node_id) + } else { + if ($name) { + $NSXTClusterNodes = $NSXTClusterNodesService.list().results | where {$_.display_name -eq $name} + } + else { + $NSXTClusterNodes = $NSXTClusterNodesService.list().results + } + } + + foreach ($NSXTClusterNode in $NSXTClusterNodes) { + + $results = [NSXTClusterNode]::new() + $results.Name = $NSXTClusterNode.display_name; + $results.node_id = $NSXTClusterNode.Id; + $results.Tags = $NSXTClusterNode.tags; + $results.controller_role = $NSXTClusterNode.controller_role; + $results.manager_role = $NSXTClusterNode.manager_role; + $results.protection = $NSXTClusterNode.protection; + $results.appliance_mgmt_listen_addr = $NSXTClusterNode.appliance_mgmt_listen_addr; + $results.external_id = $NSXTClusterNode.external_id; + $results.description = $NSXTClusterNode.description + + if ($NSXTClusterNode.manager_role -ne $null) { + $results.role = "Manager" + } + elseif ($NSXTClusterNode.controller_role -ne $null) { + $results.role = "Controller" + } + + $results + } + } +} + # Working Set Functions Function Set-NSXTLogicalRouter { <# @@ -1453,11 +1531,11 @@ Function Remove-NSXTIPAMIPBlock { [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='High')] - Param ( - [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] - [ValidateNotNullOrEmpty()] - [Alias("Id")] - [string]$block_id + Param ( + [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] + [ValidateNotNullOrEmpty()] + [Alias("Id")] + [string]$block_id ) Begin @@ -1664,13 +1742,13 @@ Function Set-NSXTIPPool { .DESCRIPTION Creates a IP Pool with a number of required parameters. Supported IP formats include 192.168.1.1, 192.168.1.1-192.168.1.100, 192.168.0.0/24 .EXAMPLE - Set-NSXTIPPool -display_name "Pool Name" -allocation_start "192.168.1.1" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" + Set-NSXTIPPool -display_name "Pool Name" -allocation_start "192.168.1.2" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" .EXAMPLE - Set-NSXTIPPool -display_name "Test Pool Name" -allocation_start "192.168.1.1" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" -dns_nameservers "192.168.1.1" -gateway_ip "192.168.1.1" + Set-NSXTIPPool -display_name "Test Pool Name" -allocation_start "192.168.1.2" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" -dns_nameservers "192.168.1.1" -gateway_ip "192.168.1.1" -dns_suffix "evil corp" #> [CmdletBinding(SupportsShouldProcess=$true, - ConfirmImpact='Medium')] + ConfirmImpact='High')] # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types Param ( @@ -1684,6 +1762,9 @@ Function Set-NSXTIPPool { [parameter(Mandatory=$false)] [string]$dns_nameservers, + [parameter(Mandatory=$false)] + [string]$dns_suffix, + [parameter(Mandatory=$true)] [ValidateNotNullOrEmpty()] [string]$allocation_start, @@ -1720,17 +1801,16 @@ Function Set-NSXTIPPool { class allocation_ranges { [string]$start [string]$end - $self + #$self } class subnets { - [string]$dns_nameservers + [array]$allocation_ranges = [allocation_ranges]::new() + [array]$dns_nameservers [string]$dns_suffix [string]$cidr [string]$gateway_ip - $allocation_ranges = [allocation_ranges]::new() - hidden $self - + #hidden $self } class ip_pool { @@ -1738,42 +1818,51 @@ Function Set-NSXTIPPool { [string]$description [string]$resource_type = 'IpPool' [long]$revision = '0' - $subnets = [subnets]::new() + [array]$subnets = [subnets]::new() hidden $pool_usage - hidden $tags - hidden $self - hidden $links = [System.Collections.Generic.List[string]]::new() + hidden [array]$tags + # hidden $self + hidden $links } - } Process { - $ip_pool = $NSXTIPPoolService.help.create.ip_pool.Create() - $ip_pool.subnets = $NSXTIPPoolService.help.create.ip_pool.subnets.Create() - $ip_pool.subnets = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.Create() - $ip_pool.subnets.allocation_ranges = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.create() - $ip_pool.subnets.allocation_ranges = $NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.element.create() + $sample_ip_pool = $NSXTIPPoolService.help.create.ip_pool.Create() + $sample_ip_pool.subnets = @($NSXTIPPoolService.help.create.ip_pool.subnets.Create()) + $sample_ip_pool.subnets = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.Create()) + $sample_ip_pool.subnets[0].allocation_ranges = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.create()) + $sample_ip_pool.subnets[0].allocation_ranges = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.element.create()) + #Remove buggy self object + $ip_pool = $sample_ip_pool | select -Property * -ExcludeProperty self + $ip_pool.subnets[0] = $sample_ip_pool.subnets[0] | select -Property * -ExcludeProperty self + $ip_pool.subnets[0].allocation_ranges[0] = $sample_ip_pool.subnets[0].allocation_ranges[0] | select -Property * -ExcludeProperty self + + # Assign objects $ip_pool.display_name = $display_name $ip_pool.description = $description $ip_pool.resource_type = "IpPool" - $ip_pool.subnets.dns_nameservers = $dns_nameservers - $ip_pool.subnets.allocation_ranges.start = $allocation_start - $ip_pool.subnets.allocation_ranges.end = $allocation_end - $ip_pool.subnets.cidr = $cidr - $ip_pool.subnets.gateway_ip = $gateway_ip + $ip_pool.subnets[0].dns_nameservers = @($dns_nameservers) + $ip_pool.subnets[0].dns_suffix = $dns_suffix + $ip_pool.subnets[0].allocation_ranges[0].start = $allocation_start + $ip_pool.subnets[0].allocation_ranges[0].end = $allocation_end + $ip_pool.subnets[0].cidr = $cidr + $ip_pool.subnets[0].gateway_ip = $gateway_ip $ip_pool.revision = 0 + $ip_pool.tags = @() # Accepted JSON object ok yet it did not interpret any of the parameters - #$ip_pool_json = ConvertTo-Json $ip_pool + $ip_pool_json = ConvertTo-Json $ip_pool -Depth 10 try { # Should process if ($pscmdlet.ShouldProcess($ip_pool.display_name, "Create IP Pool")) { - $NSXTIPPool = $NSXTIPPoolService.create($ip_pool) + $ip_pool_json + #$NSXTIPPool = $NSXTIPPoolService.create($ip_pool_json) + $NSXTIPPoolService.create($ip_pool_json) } } @@ -1784,10 +1873,14 @@ Function Set-NSXTIPPool { throw } - $NSXTIPPool + #$NSXTIPPool } } +########################### +# # +# TEMPLATES!! # +# # ########################### # Get Template @@ -1934,6 +2027,8 @@ Function Set-NSXTThingTemplate { $logical_THING_request.replication_mode = $replication_mode $logical_THING_request.ip_pool_id = $ip_pool_id + $logical_THING_request_json = ConvertTo-Json $logical_THING_request -Depth 10 + try { # Should process @@ -1967,7 +2062,7 @@ Function Remove-NSXTThingTemplate { [CmdletBinding(SupportsShouldProcess=$true, ConfirmImpact='High')] - Param ( + Param ( [parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true)] [ValidateNotNullOrEmpty()] [Alias("Id")] @@ -2011,6 +2106,5 @@ Function Remove-NSXTThingTemplate { } } -$NSXTIPSubnetsService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_subnets" From 179cfa82bee88f33e57927d30570f4104bfdf77a Mon Sep 17 00:00:00 2001 From: AndyG Date: Wed, 19 Sep 2018 21:35:23 -0500 Subject: [PATCH 37/50] Set-NSXTIPPool finally working Set-NSXTIPPool finally working --- Modules/NSXT/NSXT.psm1 | 275 ++++++++++++++++++++--------------------- 1 file changed, 135 insertions(+), 140 deletions(-) diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index 99e149b..3a0d270 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -1515,6 +1515,141 @@ Function Set-NSXTIPAMIPBlock { } } +Function Set-NSXTIPPool { + <# + .Synopsis + Creates an IP Pool + .DESCRIPTION + Creates a IP Pool with a number of required parameters. Supported IP formats include 192.168.1.1, 192.168.1.1-192.168.1.100, 192.168.0.0/24 + .EXAMPLE + Set-NSXTIPPool -display_name "Pool Name" -allocation_start "192.168.1.2" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" + .EXAMPLE + Set-NSXTIPPool -display_name "Test Pool Name" -allocation_start "192.168.1.2" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" -dns_nameservers "192.168.1.1" -gateway_ip "192.168.1.1" -dns_suffix "evil corp" +#> + + [CmdletBinding(SupportsShouldProcess=$true, + ConfirmImpact='High')] + + # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types + Param ( + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$display_name, + + [parameter(Mandatory=$false)] + [string]$description, + + [parameter(Mandatory=$false)] + [string]$dns_nameservers, + + [parameter(Mandatory=$false)] + [string]$dns_suffix, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$allocation_start, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$allocation_end, + + [parameter(Mandatory=$true)] + [ValidateNotNullOrEmpty()] + [string]$cidr, + + [parameter(Mandatory=$false)] + [string]$gateway_ip + ) + + Begin + { + if (-not $global:DefaultNsxtServers.isconnected) + { + try + { + Connect-NsxtServer -Menu -ErrorAction Stop + } + + catch + { + throw "Could not connect to an NSX-T Manager, please try again" + } + } + + $NSXTIPPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools" + + class allocation_ranges { + [string]$start + [string]$end + #$self + } + + class subnets { + [array]$allocation_ranges = [allocation_ranges]::new() + [array]$dns_nameservers + [string]$dns_suffix + [string]$cidr + [string]$gateway_ip + #hidden $self + } + + class ip_pool { + [string]$display_name + [string]$description + [string]$resource_type = 'IpPool' + [long]$revision = '0' + [array]$subnets = [subnets]::new() + hidden $pool_usage + hidden [array]$tags + # hidden $self + hidden $links + } + } + + Process + { + $sample_ip_pool = $NSXTIPPoolService.help.create.ip_pool.Create() + $sample_ip_pool.subnets = @($NSXTIPPoolService.help.create.ip_pool.subnets.Create()) + $sample_ip_pool.subnets = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.Create()) + $sample_ip_pool.subnets[0].allocation_ranges = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.create()) + $sample_ip_pool.subnets[0].allocation_ranges = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.element.create()) + + #Remove buggy self object + $ip_pool = $sample_ip_pool | select -Property * -ExcludeProperty self + $ip_pool.subnets[0] = $sample_ip_pool.subnets[0] | select -Property * -ExcludeProperty self + $ip_pool.subnets[0].allocation_ranges[0] = $sample_ip_pool.subnets[0].allocation_ranges[0] | select -Property * -ExcludeProperty self + + # Assign objects + $ip_pool.display_name = $display_name + $ip_pool.description = $description + $ip_pool.resource_type = "IpPool" + $ip_pool.subnets[0].dns_nameservers = @($dns_nameservers) + $ip_pool.subnets[0].dns_suffix = $dns_suffix + $ip_pool.subnets[0].allocation_ranges[0].start = $allocation_start + $ip_pool.subnets[0].allocation_ranges[0].end = $allocation_end + $ip_pool.subnets[0].cidr = $cidr + $ip_pool.subnets[0].gateway_ip = $gateway_ip + $ip_pool.revision = 0 + $ip_pool.tags = @() + + try + { + # Should process + if ($pscmdlet.ShouldProcess($ip_pool.display_name, "Create IP Pool")) + { + $NSXTIPPoolService.create($ip_pool) + } + } + + catch + { + $Error[0].Exception.ServerError.data + # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file; grep POOL-MGMT + throw + } + } +} + # Remove functions Function Remove-NSXTIPAMIPBlock { <# @@ -1735,147 +1870,7 @@ Function Set-NSXTTraceFlow { } } -Function Set-NSXTIPPool { - <# - .Synopsis - Creates an IP Pool - .DESCRIPTION - Creates a IP Pool with a number of required parameters. Supported IP formats include 192.168.1.1, 192.168.1.1-192.168.1.100, 192.168.0.0/24 - .EXAMPLE - Set-NSXTIPPool -display_name "Pool Name" -allocation_start "192.168.1.2" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" - .EXAMPLE - Set-NSXTIPPool -display_name "Test Pool Name" -allocation_start "192.168.1.2" -allocation_end "192.168.1.100" -cidr "192.168.1.0/24" -dns_nameservers "192.168.1.1" -gateway_ip "192.168.1.1" -dns_suffix "evil corp" -#> - [CmdletBinding(SupportsShouldProcess=$true, - ConfirmImpact='High')] - - # Paramameter Set variants will be needed Multicast & Broadcast Traffic Types as well as VM & Logical Port Types - Param ( - [parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string]$display_name, - - [parameter(Mandatory=$false)] - [string]$description, - - [parameter(Mandatory=$false)] - [string]$dns_nameservers, - - [parameter(Mandatory=$false)] - [string]$dns_suffix, - - [parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string]$allocation_start, - - [parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string]$allocation_end, - - [parameter(Mandatory=$true)] - [ValidateNotNullOrEmpty()] - [string]$cidr, - - [parameter(Mandatory=$false)] - [string]$gateway_ip - ) - - Begin - { - if (-not $global:DefaultNsxtServers.isconnected) - { - try - { - Connect-NsxtServer -Menu -ErrorAction Stop - } - - catch - { - throw "Could not connect to an NSX-T Manager, please try again" - } - } - - $NSXTIPPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools" - - class allocation_ranges { - [string]$start - [string]$end - #$self - } - - class subnets { - [array]$allocation_ranges = [allocation_ranges]::new() - [array]$dns_nameservers - [string]$dns_suffix - [string]$cidr - [string]$gateway_ip - #hidden $self - } - - class ip_pool { - [string]$display_name - [string]$description - [string]$resource_type = 'IpPool' - [long]$revision = '0' - [array]$subnets = [subnets]::new() - hidden $pool_usage - hidden [array]$tags - # hidden $self - hidden $links - } - } - - Process - { - $sample_ip_pool = $NSXTIPPoolService.help.create.ip_pool.Create() - $sample_ip_pool.subnets = @($NSXTIPPoolService.help.create.ip_pool.subnets.Create()) - $sample_ip_pool.subnets = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.Create()) - $sample_ip_pool.subnets[0].allocation_ranges = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.create()) - $sample_ip_pool.subnets[0].allocation_ranges = @($NSXTIPPoolService.help.create.ip_pool.subnets.Element.allocation_ranges.element.create()) - - #Remove buggy self object - $ip_pool = $sample_ip_pool | select -Property * -ExcludeProperty self - $ip_pool.subnets[0] = $sample_ip_pool.subnets[0] | select -Property * -ExcludeProperty self - $ip_pool.subnets[0].allocation_ranges[0] = $sample_ip_pool.subnets[0].allocation_ranges[0] | select -Property * -ExcludeProperty self - - # Assign objects - $ip_pool.display_name = $display_name - $ip_pool.description = $description - $ip_pool.resource_type = "IpPool" - $ip_pool.subnets[0].dns_nameservers = @($dns_nameservers) - $ip_pool.subnets[0].dns_suffix = $dns_suffix - $ip_pool.subnets[0].allocation_ranges[0].start = $allocation_start - $ip_pool.subnets[0].allocation_ranges[0].end = $allocation_end - $ip_pool.subnets[0].cidr = $cidr - $ip_pool.subnets[0].gateway_ip = $gateway_ip - $ip_pool.revision = 0 - $ip_pool.tags = @() - - # Accepted JSON object ok yet it did not interpret any of the parameters - $ip_pool_json = ConvertTo-Json $ip_pool -Depth 10 - - try - { - # Should process - if ($pscmdlet.ShouldProcess($ip_pool.display_name, "Create IP Pool")) - { - $ip_pool_json - #$NSXTIPPool = $NSXTIPPoolService.create($ip_pool_json) - $NSXTIPPoolService.create($ip_pool_json) - } - } - - catch - { - $Error[0].Exception.ServerError.data - # more error data found in the NSX-T Manager /var/log/vmware/nsx-manager.log file; grep POOL-MGMT - throw - } - - #$NSXTIPPool - } -} ########################### # # From 3a022777d37e9dff6b2b9fdadc03567fcd650fb7 Mon Sep 17 00:00:00 2001 From: AndyG Date: Wed, 19 Sep 2018 22:06:01 -0500 Subject: [PATCH 38/50] Removed unnecessary JSON conversion in template Removed unnecessary JSON conversion in template --- Modules/NSXT/NSXT.psm1 | 2 -- 1 file changed, 2 deletions(-) diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index 3a0d270..6d52412 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -2022,8 +2022,6 @@ Function Set-NSXTThingTemplate { $logical_THING_request.replication_mode = $replication_mode $logical_THING_request.ip_pool_id = $ip_pool_id - $logical_THING_request_json = ConvertTo-Json $logical_THING_request -Depth 10 - try { # Should process From 5052044ae1c7cfd35c85be6d18eaf17a96733e81 Mon Sep 17 00:00:00 2001 From: AndyG Date: Wed, 19 Sep 2018 22:08:39 -0500 Subject: [PATCH 39/50] Added Comment to Set-NSXTIPPool Added Comment to Set-NSXTIPPool --- Modules/NSXT/NSXT.psm1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/Modules/NSXT/NSXT.psm1 b/Modules/NSXT/NSXT.psm1 index 6d52412..4e135e8 100644 --- a/Modules/NSXT/NSXT.psm1 +++ b/Modules/NSXT/NSXT.psm1 @@ -1577,7 +1577,8 @@ Function Set-NSXTIPPool { } $NSXTIPPoolService = Get-NsxtService -Name "com.vmware.nsx.pools.ip_pools" - + + # Classes unused - part of early testing class allocation_ranges { [string]$start [string]$end From a1c3c01f05f59ebf33f02fa20e9f6b23bdd49247 Mon Sep 17 00:00:00 2001 From: William Lam Date: Thu, 20 Sep 2018 04:56:43 -0700 Subject: [PATCH 40/50] Added NSX-T Policy Firewall cmdlets --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 index c7feb19..9eca367 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psd1 @@ -36,7 +36,7 @@ Description = 'PowerShell Module for Managing NSX-T on VMware Cloud on AWS' PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService' +FunctionsToExport = 'Connect-NSXTProxy', 'Get-NSXTSegment', 'New-NSXTSegment', 'Remove-NSXTSegment', 'Get-NSXTGroup', 'New-NSXTGroup', 'Remove-NSXTGroup', 'Get-NSXTService', 'New-NSXTService', 'Get-NSXTFirewall', 'New-NSXTFirewall', 'Remove-NSXTFirewall' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() From 8402e6999384464c94b3fefa4ff1c5ca6f1d8243 Mon Sep 17 00:00:00 2001 From: William Lam Date: Thu, 20 Sep 2018 05:04:18 -0700 Subject: [PATCH 41/50] Fixed caps --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index 09b6b4d..b87d788 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -688,7 +688,7 @@ Function New-NSXTGroup { } } -Function Remove-NSXTGROUP { +Function Remove-NSXTGroup { <# .NOTES =========================================================================== @@ -704,7 +704,7 @@ Function Remove-NSXTGROUP { .DESCRIPTION This cmdlet removes an NSX-T Group .EXAMPLE - Remove-NSXTGROUP -Id Foo -GatewayType MGW -Troubleshoot + Remove-NSXTGroup -Id Foo -GatewayType MGW -Troubleshoot #> Param ( [Parameter(Mandatory=$True)]$Id, From ea4ab5f61d806f80925f06dcf5cf660944a01afb Mon Sep 17 00:00:00 2001 From: William Lam Date: Mon, 24 Sep 2018 14:17:39 -0700 Subject: [PATCH 42/50] Updated function to support Cloud Motion & other HCX Migrations --- Modules/VMware.HCX/VMware.HCX.psd1 | 4 +- Modules/VMware.HCX/VMware.HCX.psm1 | 407 ++++++++++++++++++++++++++++- 2 files changed, 407 insertions(+), 4 deletions(-) diff --git a/Modules/VMware.HCX/VMware.HCX.psd1 b/Modules/VMware.HCX/VMware.HCX.psd1 index de1f200..cd957ac 100644 --- a/Modules/VMware.HCX/VMware.HCX.psd1 +++ b/Modules/VMware.HCX/VMware.HCX.psd1 @@ -12,7 +12,7 @@ RootModule = 'VMware.HCX.psm1' # Version number of this module. -ModuleVersion = '1.0.0' +ModuleVersion = '1.0.1' # Supported PSEditions # CompatiblePSEditions = @() @@ -36,7 +36,7 @@ Description = 'PowerShell Module for Managing Hybrid Cloud Extension (HCX) on VM PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Connect-HcxVAMI', 'Get-HcxVAMIVCConfig' +FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI', 'Get-HcxVCConfig' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Modules/VMware.HCX/VMware.HCX.psm1 b/Modules/VMware.HCX/VMware.HCX.psm1 index 222f8d1..c066f87 100644 --- a/Modules/VMware.HCX/VMware.HCX.psm1 +++ b/Modules/VMware.HCX/VMware.HCX.psm1 @@ -94,6 +94,409 @@ Function Get-HcxCloudConfig { } } +Function Get-HcxEndpoint { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/24/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + List all HCX endpoints (onPrem and Cloud) + .DESCRIPTION + This cmdlet lists all HCX endpoints (onPrem and Cloud) + .EXAMPLE + Get-HcxEndpoint -cloudVCConnection $cloudVCConnection +#> + Param ( + [Parameter(Mandatory=$true)]$cloudVCConnection + ) + + If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxManager " } Else { + #Cloud HCX Manager + $cloudHCXConnectionURL = $global:hcxConnection.Server + "/cloudConfigs" + + if($PSVersionTable.PSEdition -eq "Core") { + $cloudRequests = Invoke-WebRequest -Uri $cloudHCXConnectionURL -Method GET -Headers $global:hcxConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $cloudRequests = Invoke-WebRequest -Uri $cloudHCXConnectionURL -Method GET -Headers $global:hcxConnection.headers -UseBasicParsing + } + $cloudData = ($cloudRequests.Content | ConvertFrom-Json).data.items[0] + + $hcxInventoryUrl = $global:hcxConnection.Server + "/service/inventory/resourcecontainer/list" + + $payload = @{ + "cloud" = @{ + "local"="true"; + "remote"="true"; + } + } + $body = $payload | ConvertTo-Json + + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $hcxInventoryUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $hcxInventoryUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing + } + if($requests.StatusCode -eq 200) { + $items = ($requests.Content | ConvertFrom-Json).data.items + + $results = @() + foreach ($item in $items) { + $tmp = [pscustomobject] @{ + SourceResourceName = $item.resourceName; + SourceResourceType = $item.resourceType; + SourceResourceId = $item.resourceId; + SourceEndpointName = $item.endpoint.name; + SourceEndpointType = "VC" + SourceEndpointId = $item.endpoint.endpointId; + RemoteResourceName = $cloudVCConnection.name; + RemoteResourceType = "VC" + RemoteResourceId = $cloudVCConnection.InstanceUuid + RemoteEndpointName = $cloudData.cloudName; + RemoteEndpointType = $cloudData.cloudType; + RemoteEndpointId = $cloudData.endpointId; + } + $results+=$tmp + } + return $results + } else { + Write-Error "Failed to list HCX Connection Resources" + } + } +} + +Function New-HcxMigration { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/24/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Initiate a "Bulk" migrations supporting Cold, vMotion, VR or new Cloud Motion + .DESCRIPTION + This cmdlet initiates a "Bulk" migrations supporting Cold, vMotion, VR or new Cloud Motionn + .EXAMPLE + Validate Migration request only + + New-HcxMigration -onPremVCConnection $onPremVC -cloudVCConnection $cloudVC ` + -MigrationType bulkVMotion ` + -VMs @("SJC-CNA-34","SJC-CNA-35","SJC-CNA-36") ` + -NetworkMappings @{"SJC-CORP-WORKLOADS"="sddc-cgw-network-1";"SJC-CORP-INTERNAL-1"="sddc-cgw-network-2";"SJC-CORP-INTERNAL-2"="sddc-cgw-network-3"} ` + -StartTime "Sep 24 2018 1:30 PM" ` + -EndTime "Sep 24 2018 2:30 PM" + .EXAMPLE + Start Migration request + + New-HcxMigration -onPremVCConnection $onPremVC -cloudVCConnection $cloudVC ` + -MigrationType bulkVMotion ` + -VMs @("SJC-CNA-34","SJC-CNA-35","SJC-CNA-36") ` + -NetworkMappings @{"SJC-CORP-WORKLOADS"="sddc-cgw-network-1";"SJC-CORP-INTERNAL-1"="sddc-cgw-network-2";"SJC-CORP-INTERNAL-2"="sddc-cgw-network-3"} ` + -StartTime "Sep 24 2018 1:30 PM" ` + -EndTime "Sep 24 2018 2:30 PM" ` + -MigrationType bulkVMotion +#> + Param ( + [Parameter(Mandatory=$true)][String[]]$VMs, + [Parameter(Mandatory=$true)][Hashtable]$NetworkMappings, + [Parameter(Mandatory=$true)]$onPremVCConnection, + [Parameter(Mandatory=$true)]$cloudVCConnection, + [Parameter(Mandatory=$true)][String]$StartTime, + [Parameter(Mandatory=$true)][String]$EndTime, + [Parameter(Mandatory=$true)][ValidateSet("Cold","vMotion","VR","bulkVMotion")][String]$MigrationType, + [Parameter(Mandatory=$false)]$ValidateOnly=$true + ) + + If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxManager " } Else { + $hcxEndpointInfo = Get-HcxEndpoint -cloudVCConnection $cloudVCConnection + + $inputArray = @() + foreach ($vm in $VMs) { + $vmView = Get-View -Server $onPremVCConnection -ViewType VirtualMachine -Filter @{"name"=$vm} + + $cloudResourcePoolName = "Compute-ResourcePool" + $cloudFolderName = "Workloads" + $cloudDatastoreName = "WorkloadDatastore" + $cloudDatacenterName = "SDDC-Datacenter" + + $cloudResourcePool = (Get-ResourcePool -Server $cloudVCConnection -Name $cloudResourcePoolName).ExtensionData + $cloudFolder = (Get-Folder -Server $cloudVCConnection -Name $cloudFolderName).ExtensionData + $cloudDatastore = (Get-Datastore -Server $cloudVCConnection -Name $cloudDatastoreName).ExtensionData + $cloudDatacenter = (Get-Datacenter -Server $cloudVCConnection -Name $cloudDatacenterName).ExtensionData + + $placementArray = @() + $placement = @{ + "containerType"="folder"; + "containerId"=$cloudFolder.MoRef.Value; + "containerName"=$cloudFolderName; + } + $placementArray+=$placement + $placement = @{ + "containerType"="resourcePool"; + "containerId"=$cloudResourcePool.MoRef.Value; + "containerName"=$cloudResourcePoolName; + } + $placementArray+=$placement + $placement = @{ + "containerType"="dataCenter"; + "containerId"=$cloudDatacenter.MoRef.Value; + "containerName"=$cloudDatacenterName; + } + $placementArray+=$placement + + $networkArray = @() + $vmNetworks = $vmView.Network + foreach ($vmNetwork in $vmNetworks) { + if($vmNetwork.Type -eq "Network") { + $sourceNetworkType = "VirtualNetwork" + } else { $sourceNetworkType = $vmNetwork.Type } + + $sourceNetworkRef = New-Object VMware.Vim.ManagedObjectReference + $sourceNetworkRef.Type = $vmNetwork.Type + $sourceNetworkRef.Value = $vmNetwork.Value + $sourceNetwork = Get-View -Server $onPremVCConnection $sourceNetworkRef + + $sourceNetworkName = $sourceNetwork.Name + $destNetworkName = $NetworkMappings[$sourceNetworkName] + + $destNetwork = Get-VDPortGroup -Server $cloudVCConnection -Name $destNetworkName + + if($destNetwork.Id -match "DistributedVirtualPortgroup") { + $destNetworkType = "DistributedVirtualPortgroup" + $destNetworkId = ($destNetwork.Id).Replace("DistributedVirtualPortgroup-","") + } else { + $destNetworkType = "Network" + $destNetworkId = ($destNetwork.Id).Replace("Network-","") + } + + $tmp = @{ + "srcNetworkType" = $sourceNetworkType; + "srcNetworkValue" = $vmNetwork.Value; + "srcNetworkHref" = $vmNetwork.Value; + "srcNetworkName" = $sourceNetworkName; + "destNetworkType" = $destNetworkType; + "destNetworkValue" = $destNetworkId; + "destNetworkHref" = $destNetworkId; + "destNetworkName" = $destNetworkName; + } + $networkArray+=$tmp + } + + $input = @{ + "input" = @{ + "migrationType"=$MigrationType; + "entityDetails" = @{ + "entityId"=$vmView.MoRef.Value; + "entityName"=$vm; + } + "source" = @{ + "endpointType"=$hcxEndpointInfo.SourceEndpointType; + "endpointId"=$hcxEndpointInfo.SourceEndpointId; + "endpointName"=$hcxEndpointInfo.SourceEndpointName; + "resourceType"=$hcxEndpointInfo.SourceResourceType; + "resourceId"=$hcxEndpointInfo.SourceResourceId; + "resourceName"=$hcxEndpointInfo.SourceResourceName; + } + "destination" = @{ + "endpointType"=$hcxEndpointInfo.RemoteEndpointType; + "endpointId"=$hcxEndpointInfo.RemoteEndpointId; + "endpointName"=$hcxEndpointInfo.RemoteEndpointName; + "resourceType"=$hcxEndpointInfo.RemoteResourceType; + "resourceId"=$hcxEndpointInfo.RemoteResourceId; + "resourceName"=$hcxEndpointInfo.RemoteResourceName; + } + "placement" = $placementArray + "storage" = @{ + "datastoreId"=$cloudDatastore.Moref.Value; + "datastoreName"=$cloudDatastoreName; + "diskProvisionType"="thin"; + } + "networks" = @{ + "retainMac" = $true; + "targetNetworks" = $networkArray; + } + "decisionRules" = @{ + "removeSnapshots"=$true; + "removeISOs"=$true; + "forcePowerOffVm"=$false; + "upgradeHardware"=$false; + "upgradeVMTools"=$false; + } + "schedule" = @{} + } + } + $inputArray+=$input + } + + $spec = @{ + "migrations"=$inputArray + } + $body = $spec | ConvertTo-Json -Depth 20 + + Write-Verbose -Message "Pre-Validation JSON Spec: $body" + $hcxMigrationValiateUrl = $global:hcxConnection.Server+ "/migrations?action=validate" + + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $hcxMigrationValiateUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing -ContentType "application/json" -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $hcxMigrationValiateUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing -ContentType "application/json" + } + + if($requests.StatusCode -eq 200) { + $validationErrors = ($requests.Content|ConvertFrom-Json).migrations.validationInfo.validationResult.errors + if($validationErrors -ne $null) { + Write-Host -Foreground Red "`nThere were validation errors found for this HCX Migration Spec ..." + foreach ($message in $validationErrors) { + Write-Host -Foreground Yellow "`t" $message.message + } + } else { + Write-Host -Foreground Green "`nHCX Pre-Migration Spec successfully validated" + if($ValidateOnly -eq $false) { + try { + $startDateTime = $StartTime | Get-Date + } catch { + Write-Host -Foreground Red "Invalid input for -StartTime, please check for typos" + exit + } + + try { + $endDateTime = $EndTime | Get-Date + } catch { + Write-Host -Foreground Red "Invalid input for -EndTime, please check for typos" + exit + } + + $offset = (Get-TimeZone).GetUtcOffset($startDateTime).TotalMinutes + $offset = [int]($offSet.toString().replace("-","")) + + $schedule = @{ + scheduledFailover = $true; + startYear = $startDateTime.Year; + startMonth = $startDateTime.Month; + startDay = $startDateTime.Day; + startHour = $startDateTime | Get-Date -UFormat %H; + startMinute = $startDateTime | Get-Date -UFormat %M; + endYear = $endDateTime.Year; + endMonth = $endDateTime.Month; + endDay = $endDateTime.Day; + endHour = $endDateTime | Get-Date -UFormat %H; + endMinute = $endDateTime | Get-Date -UFormat %M; + timezoneOffset = $offset; + } + + foreach ($migration in $spec.migrations) { + $migration.input.schedule = $schedule + } + $body = $spec | ConvertTo-Json -Depth 8 + + Write-Verbose -Message "Validated JSON Spec: $body" + $hcxMigrationStartUrl = $global:hcxConnection.Server+ "/migrations?action=start" + + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $hcxMigrationStartUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing -ContentType "application/json" -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $hcxMigrationStartUrl -Body $body -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing -ContentType "application/json" + } + + if($requests.StatusCode -eq 200) { + $migrationIds = ($requests.Content | ConvertFrom-Json).migrations.migrationId + Write-Host -ForegroundColor Green "Starting HCX Migration ..." + foreach ($migrationId in $migrationIds) { + Write-Host -ForegroundColor Green "`tMigrationID: $migrationId" + } + } else { + Write-Error "Failed to start HCX Migration" + } + } + } + } else { + Write-Error "Failed to validate HCX Migration spec" + } + } +} + +Function Get-HcxMigration { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/24/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + List all HCX Migrations that are in-progress, have completed or failed + .DESCRIPTION + This cmdlet lists ist all HCX Migrations that are in-progress, have completed or failed + .EXAMPLE + List all HCX Migrations + + Get-HcxMigration + .EXAMPLE + List all running HCX Migrations + + Get-HcxMigration -RunningMigrations + .EXAMPLE + List all HCX Migrations + + Get-HcxMigration -MigrationId +#> + Param ( + [Parameter(Mandatory=$false)][String]$MigrationId, + [Switch]$RunningMigrations + ) + + If (-Not $global:hcxConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxManager " } Else { + $spec = @{} + $body = $spec | ConvertTo-Json + + $hcxQueryUrl = $global:hcxConnection.Server + "/migrations?action=query" + if($PSVersionTable.PSEdition -eq "Core") { + $requests = Invoke-WebRequest -Uri $hcxQueryUrl -Method POST -body $body -Headers $global:hcxConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $requests = Invoke-WebRequest -Uri $hcxQueryUrl -Method POST -Headers $global:hcxConnection.headers -UseBasicParsing + } + + $migrations = ($requests.content | ConvertFrom-Json).rows + + if($PSBoundParameters.ContainsKey("MigrationId")){ + $migrations = $migrations | where { $_.migrationId -eq $MigrationId } + } + + if($RunningMigrations){ + $migrations = $migrations | where { $_.jobInfo.state -ne "MIGRATE_FAILED" -and $_.jobInfo.state -ne "MIGRATE_CANCELED"-and $_.jobInfo.state -ne "MIGRATED" } + } + + $results = @() + foreach ($migration in $migrations) { + $tmp = [pscustomobject] @{ + ID = $migration.migrationId; + VM = $migration.migrationInfo.entityDetails.entityName; + State = $migration.jobInfo.state; + Progress = ($migration.migrationInfo.progressDetails.progressPercentage).toString() + " %"; + DataCopied = ([math]::round($migration.migrationInfo.progressDetails.diskCopyBytes/1Gb, 2)).toString() + " GB"; + Message = $migration.migrationInfo.message; + InitiatedBy = $migration.jobInfo.username; + CreateDate = $migration.jobInfo.creationDate; + LastUpdated = $migration.jobInfo.lastUpdated; + } + $results+=$tmp + } + $results + } +} + Function Connect-HcxVAMI { <# .NOTES @@ -136,7 +539,7 @@ Function Connect-HcxVAMI { $global:hcxVAMIConnection } -Function Get-HcxVAMIVCConfig { +Function Get-HcxVCConfig { <# .NOTES =========================================================================== @@ -152,7 +555,7 @@ Function Get-HcxVAMIVCConfig { .DESCRIPTION This cmdlet returns the onPrem vCenter Server registered with HCX Manager .EXAMPLE - Get-HcxVAMIVCConfig + Get-HcxVCConfig #> If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { $vcConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/vcenter" From 82b5b2eb1e85a598314f8bd0583b7ebadb412b3d Mon Sep 17 00:00:00 2001 From: William Lam Date: Thu, 27 Sep 2018 15:55:12 -0700 Subject: [PATCH 43/50] Adding VM & Criteria types into Get-NSXTGroup function --- Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 index b87d788..3bfdfe3 100644 --- a/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 +++ b/Modules/VMware.VMC.NSXT/VMware.VMC.NSXT.psm1 @@ -605,7 +605,13 @@ Function Get-NSXTGroup { $members = @() foreach ($member in $group.expression) { - $members += $member.ip_addresses + if($member.ip_addresses) { + $members += $member.ip_addresses + } else { + if($member.resource_type -eq "Condition") { + $members += $member.value + } + } } $tmp = [pscustomobject] @{ From b25c2807149fc9d8267ac8e5b9a8f76ebd06e2a9 Mon Sep 17 00:00:00 2001 From: Doug Taliaferro Date: Wed, 3 Oct 2018 21:09:18 -0400 Subject: [PATCH 44/50] Sample script to set VM tags in the guestinfo --- Scripts/Set-TagsInGuestinfo.ps1 | 98 +++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 Scripts/Set-TagsInGuestinfo.ps1 diff --git a/Scripts/Set-TagsInGuestinfo.ps1 b/Scripts/Set-TagsInGuestinfo.ps1 new file mode 100644 index 0000000..e895759 --- /dev/null +++ b/Scripts/Set-TagsInGuestinfo.ps1 @@ -0,0 +1,98 @@ +<# +.NOTES + Script name: Set-TagsInGuestinfo.ps1 + Created on: 10/02/2018 + Author: Doug Taliaferro, @virtually_doug + Description: Gets the vSphere Tags assigned to a VM and makes them available to the guest OS. + Dependencies: None known + + ===Tested Against Environment==== + vSphere Version: 6.5 + PowerCLI Version: 10.0.0.7893909 + PowerShell Version: 5.1.14409.1005 + OS Version: Windows 7, 10 + Keyword: VM, Tags, Guestinfo + +.SYNOPSIS + Gets the vSphere Tags assigned to a VM and makes them available to the guest OS. + +.DESCRIPTION + Gets the tags assigned to one or more VMs from one or more categories and sets the tag values + in the VM's 'guestinfo' advanced settings. This makes the tags available within the guest OS + using VM tools (vmtoolsd.exe) and allows the tags to be used as metadata for applications or + management agents that run inside the guest. + + For example, if a VM has a tag named 'Accounting' from the + category 'Departments', the advanced setting becomes: + guestinfo.Departments = Accounting + + This can be retrieved in the guest OS by running: + vmtoolsd.exe --cmd "info-get guestinfo.Departments" + + If multiple tags are assigned from the same category, they are joined using the specified + delimter (a semicolon by default): + guestinfo.Departments = Accounting;Sales + +.PARAMETER VMs + One or more VMs returned from the Get-VM cmdlet. + +.PARAMETER Categories + The names of tag categories that should be set in the advanced settings. + + .PARAMETER Delimiter + The delimiting character used for multiple tags of the same category. Defaults to a + semicolon. + +.PARAMETER vCenter + The vCenter server to connect to. Optional if you are already connected. + +.EXAMPLE + .\Set-TagsInGuestInfo.ps1 -VM (get-vm testvm01) -Categories Departments, Environment + + Gets tags assigned to 'testvm01' in the Departments and Environment categories and + sets their values in 'guestinfo.Departments' and 'guestinfo.Environment'. + +.EXAMPLE + .\Set-TagsInGuestInfo.ps1 -VM (get-cluster Dev-01 | get-vm) -Categories Departments + + Gets tags assigned to all VMs in the Dev-01 cluster and sets 'guestinfo.Departments' + on each VM. +#> +#Requires -modules VMware.VimAutomation.Core +[CmdletBinding()] +param ( + [Parameter(Mandatory=$true,Position=0)] + $VMs, + [Parameter(Mandatory=$true,Position=1)] + [string[]]$Categories, + [string]$Delimiter = ';', + [string]$vCenter +) +if ($vCenter) { + Connect-VIServer $vCenter +} + +ForEach ($categoryName in $Categories) { + $category = Get-TagCategory -Name $categoryName + if ($category) { + $guestinfoName = "guestinfo.$category" + + # Get Tag assignments for the VMs + $tags = Get-TagAssignment -Entity $VMs -Category $category + + # Group the tags by VM (in this case the Entity property of Group-Object) + $groups = $tags | Group-Object -Property Entity + + # Get each VM and set the guestinfo + ForEach ($item in $groups) { + $vm = get-vm $item.Name + # Multiple tags of the same category are joined + $guestinfoValue = $item.Group.Tag.Name -join $Delimiter + + Write-Host "$($vm): setting '$guestinfoName' = '$guestinfoValue'" + New-AdvancedSetting -Entity $vm -Name $guestinfoName -Value $guestinfoValue -Confirm:$false -Force | Out-Null + } + } else { + Write-Host "Category '$categoryName' was not found." + } +} From 0581d89cbe79ccca9968761e9a70ad11cc513113 Mon Sep 17 00:00:00 2001 From: Doug Taliaferro Date: Wed, 3 Oct 2018 21:16:50 -0400 Subject: [PATCH 45/50] Sample script to set VM tags in the guestinfo --- Scripts/Set-TagsInGuestinfo.ps1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/Scripts/Set-TagsInGuestinfo.ps1 b/Scripts/Set-TagsInGuestinfo.ps1 index e895759..c245c05 100644 --- a/Scripts/Set-TagsInGuestinfo.ps1 +++ b/Scripts/Set-TagsInGuestinfo.ps1 @@ -79,16 +79,16 @@ ForEach ($categoryName in $Categories) { # Get Tag assignments for the VMs $tags = Get-TagAssignment -Entity $VMs -Category $category - - # Group the tags by VM (in this case the Entity property of Group-Object) + + # Group the tags by VM (in this case the Entity property of Group-Object) $groups = $tags | Group-Object -Property Entity - - # Get each VM and set the guestinfo + + # Get each VM and set the guestinfo ForEach ($item in $groups) { $vm = get-vm $item.Name - # Multiple tags of the same category are joined + # Multiple tags of the same category are joined $guestinfoValue = $item.Group.Tag.Name -join $Delimiter - + Write-Host "$($vm): setting '$guestinfoName' = '$guestinfoValue'" New-AdvancedSetting -Entity $vm -Name $guestinfoName -Value $guestinfoValue -Confirm:$false -Force | Out-Null } From 4246cfc71f9f185e8d7f6ccc9460782575dbdf09 Mon Sep 17 00:00:00 2001 From: Doug Taliaferro Date: Thu, 4 Oct 2018 19:53:08 -0400 Subject: [PATCH 46/50] Script to set custom attributes in guestinfo --- Scripts/Set-CustomAttributesInGuestinfo.ps1 | 84 +++++++++++++++++++++ 1 file changed, 84 insertions(+) create mode 100644 Scripts/Set-CustomAttributesInGuestinfo.ps1 diff --git a/Scripts/Set-CustomAttributesInGuestinfo.ps1 b/Scripts/Set-CustomAttributesInGuestinfo.ps1 new file mode 100644 index 0000000..d76d3ee --- /dev/null +++ b/Scripts/Set-CustomAttributesInGuestinfo.ps1 @@ -0,0 +1,84 @@ +<# +.NOTES + Script name: Set-CustomAttributesInGuestinfo.ps1 + Created on: 10/04/2018 + Author: Doug Taliaferro, @virtually_doug + Description: Gets Custom Attributes assigned to a VM and makes them available to the guest OS. + Dependencies: None known + + ===Tested Against Environment==== + vSphere Version: 6.5 + PowerCLI Version: 10.0.0.7893909 + PowerShell Version: 5.1.14409.1005 + OS Version: Windows 7, 10 + Keyword: VM, Attributes, Guestinfo + +.SYNOPSIS + Gets Custom Attributes assigned to a VM and makes them available to the guest OS. + +.DESCRIPTION + Gets the custom attributes assigned to one or more VMs and sets their values in the + VM's 'guestinfo' advanced settings. This makes the attributes available within the + guest OS using VM tools (vmtoolsd.exe) and allows the attributes to be used as metadata + for applications or management agents that run inside the guest. If the attribute name + contains spaces they are removed in naming the advanced setting. + + For example, if a VM has a custom attribute named 'Created On', the advanced setting + becomes: + 'guestinfo.CreatedOn' = '08/08/2018 14:24:17' + + This can be retrieved in the guest OS by running: + vmtoolsd.exe --cmd "info-get guestinfo.CreatedOn" + +.PARAMETER VMs + One or more VMs returned from the Get-VM cmdlet. + +.PARAMETER Attributes + The names of the Custom Attributes to get. If the names contain spaces they must be + enclosed in quotes. The spaces will be removed to name the advanced setting. + +.PARAMETER vCenter + The vCenter server to connect to. Optional if you are already connected. + +.EXAMPLE + .\Set-CustomAttributesInGuestInfo.ps1 -VM (get-vm testvm01) -Attributes 'Created On', 'Created By' + + Gets the custom attributes 'Created On' and 'Created By' for 'testvm01' and sets their + values in 'guestinfo.CreatedOn' and 'guestinfo.CreatedBy'. + +.EXAMPLE + .\Set-CustomAttributesInGuestInfo.ps1-VM (get-cluster Dev-01 | get-vm) -Attributes 'Created On' + + Gets the custom attribute 'Created On' for all VMs in the Dev-01 cluster and sets 'guestinfo.CreatedOn' + on each VM. +#> +#Requires -modules VMware.VimAutomation.Core +[CmdletBinding()] +param ( + [Parameter(Mandatory=$true,Position=0)] + $VMs, + [Parameter(Mandatory=$true,Position=1)] + [string[]]$Attributes, + [string]$vCenter +) +if ($vCenter) { + Connect-VIServer $vCenter +} + +ForEach ($vm in $VMs) { + ForEach ($attributeName in $Attributes) { + # Get the custom attribute with a matcing key name + $customField = $vm.CustomFields | Where-Object Key -eq $attributeName + if ($customField) { + # Remove white space from the attribute name because the advanced + # setting name cannot contain spaces + $attributeNameNoSpaces = $customField.Key -replace '\s','' + $guestinfoName = "guestinfo.$attributeNameNoSpaces" + $guestinfoValue = $customField.Value + Write-Host "$($vm): setting '$guestinfoName' = '$guestinfoValue'" + New-AdvancedSetting -Entity $vm -Name $guestinfoName -Value $guestinfoValue -Confirm:$false -Force | Out-Null + } else { + Write-Host "$($vm): custom attribute '$attributeName' not set on this VM" + } + } +} From 48d2db91d8cd840c4657bef053541b8a34e778c9 Mon Sep 17 00:00:00 2001 From: William Lam Date: Tue, 9 Oct 2018 13:36:45 -0700 Subject: [PATCH 47/50] Added new functions to configure HCX Manager --- Modules/VMware.HCX/VMware.HCX.psd1 | 4 +- Modules/VMware.HCX/VMware.HCX.psm1 | 566 ++++++++++++++++++++++++++++- 2 files changed, 567 insertions(+), 3 deletions(-) diff --git a/Modules/VMware.HCX/VMware.HCX.psd1 b/Modules/VMware.HCX/VMware.HCX.psd1 index cd957ac..4e1e68b 100644 --- a/Modules/VMware.HCX/VMware.HCX.psd1 +++ b/Modules/VMware.HCX/VMware.HCX.psd1 @@ -12,7 +12,7 @@ RootModule = 'VMware.HCX.psm1' # Version number of this module. -ModuleVersion = '1.0.1' +ModuleVersion = '1.0.2' # Supported PSEditions # CompatiblePSEditions = @() @@ -36,7 +36,7 @@ Description = 'PowerShell Module for Managing Hybrid Cloud Extension (HCX) on VM PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI', 'Get-HcxVCConfig' +FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI', 'Get-HcxVCConfig', 'Set-HcxLicense', 'Set-HcxVCConfig', 'Get-HcxNSXConfig', 'Set-HcxNSXConfig', 'Get-HcxCity', 'Get-HcxLocation', 'Set-HcxLocation', 'Get-HcxRoleMapping', 'Set-HcxRoleMapping' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Modules/VMware.HCX/VMware.HCX.psm1 b/Modules/VMware.HCX/VMware.HCX.psm1 index c066f87..7e5093c 100644 --- a/Modules/VMware.HCX/VMware.HCX.psm1 +++ b/Modules/VMware.HCX/VMware.HCX.psm1 @@ -576,4 +576,568 @@ Function Get-HcxVCConfig { } $tmp } -} \ No newline at end of file +} + +Function Set-HcxLicense { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Activate HCX Manager with HCX Cloud + .DESCRIPTION + This cmdlet activates HCX Manager with HCX Cloud + .EXAMPLE + Set-HcxLicense -LicenseKey +#> + Param ( + [Parameter(Mandatory=$True)]$LicenseKey + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $hcxConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/hcx" + $method = "POST" + + $hcxConfig = @{ + config = @{ + url = "https://connect.hcx.vmware.com"; + activationKey = $LicenseKey; + } + } + + $payload = @{ + data = @{ + items = @($hcxConfig) + } + } + + $body = $payload | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$vcConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $hcxConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $hcxConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully registered HCX Manager with HCX Cloud" + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).data.items } + } else { + Write-Error "Failed to registered HCX Manager" + } + } +} + +Function Set-HcxVCConfig { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Registers on-prem vCenter Server with HCX Manager + .DESCRIPTION + This cmdlet registers on-prem vCenter Server with HCX Manager + .EXAMPLE + Set-HcxVC -VIServer -VIUsername -VIPassword +#> + Param ( + [Parameter(Mandatory=$True)]$VIServer, + [Parameter(Mandatory=$True)]$PSCServer, + [Parameter(Mandatory=$True)]$VIUsername, + [Parameter(Mandatory=$True)]$VIPassword, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $vcConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/vcenter" + $pscConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/lookupservice" + $method = "POST" + + + $bytes = [System.Text.Encoding]::ASCII.GetBytes($VIPassword) + $base64 = [System.Convert]::ToBase64String($bytes) + + $vcConfig = @{ + config = @{ + url = "https://$VIServer"; + userName = $VIUsername; + password = $base64; + } + } + + $payload = @{ + data = @{ + items = @($vcConfig) + } + } + + $body = $payload | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$vcConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $vcConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $vcConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully registered vCenter Server with HCX Manager" + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).data.items.config } + + $pscConfig = @{ + config = @{ + lookupServiceUrl = "https://$PSCServer" + providerType = "PSC" + } + } + + $payload = @{ + data = @{ + items = @($pscConfig) + } + } + + $body = $payload | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$pscConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $pscConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $pscConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully registered PSC with HCX Manager" + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).data.items.config } + + } else { + Write-Error "Failed to registered PSC Server" + } + } else { + Write-Error "Failed to registered vCenter Server" + } + } +} + +Function Get-HcxNSXConfig { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the onPrem NSX-V Server registered with HCX Manager + .DESCRIPTION + This cmdlet returns the onPrem NSX-V Server registered with HCX Manager + .EXAMPLE + Get-HcxNSXConfig +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $nsxConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/nsx" + + if($PSVersionTable.PSEdition -eq "Core") { + $nsxRequests = Invoke-WebRequest -Uri $nsxConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $nsxRequests = Invoke-WebRequest -Uri $nsxConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + $nsxData = ($nsxRequests.content | ConvertFrom-Json).data.items + + $tmp = [pscustomobject] @{ + Name = $nsxData.config.url; + Version = $nsxData.config.version; + HCXUUID = $nsxData.config.uuid; + } + $tmp + } +} + +Function Set-HcxNSXConfig { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Registers on-prem NSX-V Server with HCX Manager + .DESCRIPTION + This cmdlet registers on-prem NSX-V Server with HCX Manager + .EXAMPLE + Set-HcxNSXConfig -NSXServer -NSXUsername -NSXPassword +#> + Param ( + [Parameter(Mandatory=$True)]$NSXServer, + [Parameter(Mandatory=$True)]$NSXUsername, + [Parameter(Mandatory=$True)]$NSXPassword, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $nsxConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/nsx" + $method = "POST" + + $bytes = [System.Text.Encoding]::ASCII.GetBytes($NSXPassword) + $base64 = [System.Convert]::ToBase64String($bytes) + + $nsxConfig = @{ + config = @{ + url = "https://$NSXServer"; + userName = $NSXUsername; + password = $base64; + } + } + + $payload = @{ + data = @{ + items = @($nsxConfig) + } + } + + $body = $payload | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$nsxConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $nsxConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $nsxConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully registered NSX Server with HCX Manager" + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).data.items.config } + } else { + Write-Error "Failed to registered NSX Server" + } + return $config + } +} + +Function Get-HcxCity { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the available HCX Location based on user City and Country input + .DESCRIPTION + This cmdlet returns the available HCX Location based on user City and Country input + .EXAMPLE + Get-HcxCity -City -Country + #> + Param ( + [Parameter(Mandatory=$True)]$City, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $citySearchUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/searchCities?searchString=$City" + $method = "GET" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$citySearchUrl`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $citySearchUrl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $citySearchUrl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully returned results for City search: $City" + + $cityDetails = ($results.Content | ConvertFrom-Json).items + $cityDetails | select City,Country + } else { + Write-Error "Failed to search for city $City" + } + } + } + +Function Get-HcxLocation { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the registered City/Country location for HCX Manager + .DESCRIPTION + This cmdlet returns the registered City/Country location for HCX Manager + .EXAMPLE + Get-HcxLocation +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $locationConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/location" + + if($PSVersionTable.PSEdition -eq "Core") { + $locationRequests = Invoke-WebRequest -Uri $locationConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $locationRequests = Invoke-WebRequest -Uri $locationConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + ($locationRequests.content | ConvertFrom-Json) + } +} + +Function Set-HcxLocation { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Register HCX Manager to a specific City/Country + .DESCRIPTION + This cmdlet register HCX Manager to a specific City/Country + .EXAMPLE + Set-HcxLocation -City -Country +#> + Param ( + [Parameter(Mandatory=$True)]$City, + [Parameter(Mandatory=$True)]$Country, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $citySearchUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/searchCities?searchString=$City" + $method = "GET" + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$citySearchUrl`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $citySearchUrl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $citySearchUrl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).items } + + $locationConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/location" + $method = "PUT" + + $cityDetails = ($results.Content | ConvertFrom-Json).items + $cityDetails = $cityDetails | where { $_.city -eq $City -and $_.country -match $Country } + + if(-not $cityDetails) { + Write-Host -ForegroundColor Red "Invalid input for City and/or Country, please provide the exact input from Get-HcxCity cmdlet" + break + } + + $locationConfig = @{ + city = $cityDetails.city; + country = $cityDetails.country; + province = $cityDetails.province; + latitude = $cityDetails.latitude; + longitude = $cityDetails.longitude; + } + + $body = $locationConfig | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$locationConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $locationConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $locationConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 204) { + Write-Host -ForegroundColor Green "Successfully registered datacenter location $City to HCX Manager" + } else { + Write-Error "Failed to registerd datacenter location in HCX Manager" + } + } else { + Write-Error "Failed to search for city $City" + } + } +} +Function Get-HcxRoleMapping { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the System Admin and Enterprise User Group role mappings for HCX Manager + .DESCRIPTION + This cmdlet returns the System Admin and Enterprise User Group role mappings for HCX Manager + .EXAMPLE + Get-HcxRoleMapping + #> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $roleConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/roleMappings" + + if($PSVersionTable.PSEdition -eq "Core") { + $roleRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $roleRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + ($roleRequests.content | ConvertFrom-Json) + } + } + + Function Set-HcxRoleMapping { + <# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Configures the System Admin and Enterprise User Group role mappings for HCX Manager + .DESCRIPTION + This cmdlet configures the System Admin and Enterprise User Group role mappings for HCX Manager + .EXAMPLE + Set-HcxRoleMapping -SystemAdminGroup @("DOMAIN\GROUP") -EnterpriseAdminGroup @("DOMAIN\GROUP") + #> + Param ( + [Parameter(Mandatory=$True)][String[]]$SystemAdminGroup, + [Parameter(Mandatory=$True)][String[]]$EnterpriseAdminGroup, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $roleConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/roleMappings" + $method = "PUT" + + $roleConfig = @() + $systemAdminRole = @{ + role = "System Administrator"; + userGroups = $SystemAdminGroup + } + $enterpriseAdminRole = @{ + role = "Enterprise Administrator" + userGroups = $EnterpriseAdminGroup + } + $roleConfig+=$systemAdminRole + $roleConfig+=$enterpriseAdminRole + + $body = $roleConfig | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$locationConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $roleConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $roleConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully updated vSphere Group Mappings in HCX Manager" + } else { + Write-Error "Failed to update vSphere Group Mappings" + } + } + } \ No newline at end of file From b68dc6c4e08b7d401f77d291c56ab5c4fee7d1dc Mon Sep 17 00:00:00 2001 From: LucD Date: Thu, 25 Oct 2018 10:02:23 +0200 Subject: [PATCH 48/50] Updated VMware.VMC Fix issue #176 Added functions: - Get-VMCEdge - Get-VMCEdgeNic - Get-VMCEdgeStatus - Get-VMCEdgeNicStat - Get-VMCEdgeUplinkStat --- Modules/VMware.VMC/VMware.VMC.psd1 | Bin 8332 -> 8558 bytes Modules/VMware.VMC/VMware.VMC.psm1 | 573 ++++++++++++++++++++++------- 2 files changed, 435 insertions(+), 138 deletions(-) diff --git a/Modules/VMware.VMC/VMware.VMC.psd1 b/Modules/VMware.VMC/VMware.VMC.psd1 index b33fca99fccc962543854a8ef2a85c1d00f7e2e2..105fec0612b9384cc68ec1d1240ff768945cef05 100755 GIT binary patch delta 162 zcmeBieCM=bj}SW-g8~Rnz9=ZX_?!?UoPSpMJf{u=k}SI`LkdGWL+WICA#q+Po57DE zlOY)-A`BA=W+-7u1maSLVvx8fOdPC|0V)fUk%q~HG88c60L{r`$cD*po+ -SDDCName -GatewayType -Path "C:\Users\lamw\Desktop\VMCFirewallRules.json" #> - param( + param( [Parameter(Mandatory=$false)][String]$SDDCName, [Parameter(Mandatory=$false)][String]$OrgName, [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, [Parameter(Mandatory=$false)][String]$Path ) - if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } + if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } - if($GatewayType -eq "MGW") { + if($GatewayType -eq "MGW") { $EdgeId = "edge-1" } else { $EdgeId = "edge-2" } - $orgId = (Get-VMCOrg -Name $OrgName).Id - $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id - if(-not $orgId) { + if(-not $orgId) { Write-Host -ForegroundColor red "Unable to find Org $OrgName, please verify input" break } - if(-not $sddcId) { + if(-not $sddcId) { Write-Host -ForegroundColor red "Unable to find SDDC $SDDCName, please verify input" break } - $firewallConfigService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config + $firewallConfigService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config - $firewallRules = ($firewallConfigService.get($orgId, $sddcId, $EdgeId)).firewall_rules.firewall_rules - if(-not $ShowAll) { + $firewallRules = ($firewallConfigService.get($orgId, $sddcId, $EdgeId)).firewall_rules.firewall_rules + if(-not $ShowAll) { $firewallRules = $firewallRules | where { $_.rule_type -ne "default_policy" -and $_.rule_type -ne "internal_high" -and $_.name -ne "vSphere Cluster HA" -and $_.name -ne "Outbound Access" } | Sort-Object -Property rule_tag } else { $firewallRules = $firewallRules | Sort-Object -Property rule_tag } - $results = @() - $count = 0 - foreach ($firewallRule in $firewallRules) { + $results = @() + $count = 0 + foreach ($firewallRule in $firewallRules) { if($firewallRule.source.ip_address.Count -ne 0) { $source = $firewallRule.source.ip_address } else { @@ -473,16 +471,15 @@ Function Get-VMCFirewallRule { $count+=1 $results+=$tmp } - if($Path) { + if($Path) { Write-Host -ForegroundColor Green "Exporting $count VMC Firewall Rules to $Path ..." $results | ConvertTo-Json | Out-File $Path } else { $results | ConvertTo-Json } - } - - Function Import-VMCFirewallRule { - <# +} +Function Import-VMCFirewallRule { +<# .NOTES =========================================================================== Created by: William Lam @@ -499,43 +496,43 @@ Function Get-VMCFirewallRule { .EXAMPLE Import-VMCFirewallRule -OrgName -SDDCName -GatewayType -Path "C:\Users\lamw\Desktop\VMCFirewallRules.json" #> - param( + param( [Parameter(Mandatory=$false)][String]$SDDCName, [Parameter(Mandatory=$false)][String]$OrgName, [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, [Parameter(Mandatory=$false)][String]$Path ) - if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } + if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } - if($GatewayType -eq "MGW") { + if($GatewayType -eq "MGW") { $EdgeId = "edge-1" } else { $EdgeId = "edge-2" } - $orgId = (Get-VMCOrg -Name $OrgName).Id - $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id - if(-not $orgId) { + if(-not $orgId) { Write-Host -ForegroundColor red "Unable to find Org $OrgName, please verify input" break } - if(-not $sddcId) { + if(-not $sddcId) { Write-Host -ForegroundColor red "Unable to find SDDC $SDDCName, please verify input" break } - $firewallService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules + $firewallService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules - $vmcFirewallRulesJSON = Get-Content -Raw $Path | ConvertFrom-Json + $vmcFirewallRulesJSON = Get-Content -Raw $Path | ConvertFrom-Json - # Create top level Firewall Rules Object - $firewallRules = $firewallService.Help.add.firewall_rules.Create() - # Create top top level Firewall Rule Spec which will be an array of individual Firewall rules as we process them in next section - $ruleSpec = $firewallService.Help.add.firewall_rules.firewall_rules.Create() + # Create top level Firewall Rules Object + $firewallRules = $firewallService.Help.add.firewall_rules.Create() + # Create top top level Firewall Rule Spec which will be an array of individual Firewall rules as we process them in next section + $ruleSpec = $firewallService.Help.add.firewall_rules.firewall_rules.Create() - foreach ($vmcFirewallRule in $vmcFirewallRulesJSON) { + foreach ($vmcFirewallRule in $vmcFirewallRulesJSON) { # Create Individual Firewall Rule Element Spec $ruleElementSpec = $firewallService.Help.add.firewall_rules.firewall_rules.Element.Create() @@ -632,14 +629,13 @@ Function Get-VMCFirewallRule { Write-host "Creating VMC Firewall Rule Spec:" $vmcFirewallRule.Name "..." $ruleSpecAdd = $ruleSpec.Add($ruleElementSpec) } - $firewallRules.firewall_rules = $ruleSpec + $firewallRules.firewall_rules = $ruleSpec - Write-host "Adding VMC Firewall Rules ..." - $firewallRuleAdd = $firewallService.add($orgId,$sddcId,$EdgeId,$firewallRules) - } - - Function Remove-VMCFirewallRule { - <# + Write-host "Adding VMC Firewall Rules ..." + $firewallRuleAdd = $firewallService.add($orgId,$sddcId,$EdgeId,$firewallRules) +} +Function Remove-VMCFirewallRule { +<# .NOTES =========================================================================== Created by: William Lam @@ -656,38 +652,37 @@ Function Get-VMCFirewallRule { .EXAMPLE Remove-VMCFirewallRule -OrgName -SDDCName -GatewayType -RuleId #> - param( + param( [Parameter(Mandatory=$false)][String]$SDDCName, [Parameter(Mandatory=$false)][String]$OrgName, [Parameter(Mandatory=$true)][ValidateSet("MGW","CGW")][String]$GatewayType, [Parameter(Mandatory=$false)][String]$RuleId ) - if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } + if (-not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect"; break } - if($GatewayType -eq "MGW") { + if($GatewayType -eq "MGW") { $EdgeId = "edge-1" } else { $EdgeId = "edge-2" } - $orgId = (Get-VMCOrg -Name $OrgName).Id - $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id - if(-not $orgId) { + if(-not $orgId) { Write-Host -ForegroundColor red "Unable to find Org $OrgName, please verify input" break } - if(-not $sddcId) { + if(-not $sddcId) { Write-Host -ForegroundColor red "Unable to find SDDC $SDDCName, please verify input" break } - $firewallService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules - Write-Host "Removing VMC Firewall Rule Id $RuleId ..." - $firewallService.delete($orgId,$sddcId,$EdgeId,$RuleId) - } - + $firewallService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config.rules + Write-Host "Removing VMC Firewall Rule Id $RuleId ..." + $firewallService.delete($orgId,$sddcId,$EdgeId,$RuleId) +} Function Get-VMCLogicalNetwork { <# .NOTES @@ -727,9 +722,17 @@ Function Get-VMCLogicalNetwork { break } - $logicalNetworkService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.logical + # @LucD22 - 21/10/18 - Fix for issue #176 VMware.VMC module only lists firts 20 Logical networks + # Loop until entries (total_count) are returned - $logicalNetworks = ($logicalNetworkService.get_0($orgId, $sddcId)).data | Sort-Object -Property id + $index = [long]0 + + $logicalNetworks = do{ + $netData = $logicalNetworkService.get_0($orgId,$sddcId,$pagesize,$index) + $netData.data | Sort-Object -Property id + $index = $index + $netdata.paging_info.page_size + } + until($index -ge $netData.paging_info.total_count) if($LogicalNetworkName) { $logicalNetworks = $logicalNetworks | Where-Object {$_.Name -eq $LogicalNetworkName} @@ -751,7 +754,6 @@ Function Get-VMCLogicalNetwork { } $results } - Function Remove-VMCLogicalNetwork { <# .NOTES @@ -799,25 +801,24 @@ Function Remove-VMCLogicalNetwork { $logicalNetworkService = Get-VmcService com.vmware.vmc.orgs.sddcs.networks.logical $logicalNetworkService.delete($orgId,$sddcId,$lsId) } - Function New-VMCLogicalNetwork { - <# - .NOTES - =========================================================================== - Created by: Kyle Ruddy - Date: 03/06/2018 - Organization: VMware - Blog: https://thatcouldbeaproblem.com - Twitter: @kmruddy - =========================================================================== +<# + .NOTES + =========================================================================== + Created by: Kyle Ruddy + Date: 03/06/2018 + Organization: VMware + Blog: https://thatcouldbeaproblem.com + Twitter: @kmruddy + =========================================================================== - .SYNOPSIS - Creates a new Logical Network - .DESCRIPTION - Creates a new Logical Network - .EXAMPLE - New-VMCLogicalNetwork -OrgName -SDDCName -LogicalNetworkName -SubnetMask -Gateway - #> + .SYNOPSIS + Creates a new Logical Network + .DESCRIPTION + Creates a new Logical Network + .EXAMPLE + New-VMCLogicalNetwork -OrgName -SDDCName -LogicalNetworkName -SubnetMask -Gateway +#> [cmdletbinding(SupportsShouldProcess = $true,ConfirmImpact='High')] param( [Parameter(Mandatory=$true)][String]$SDDCName, @@ -854,7 +855,6 @@ Function New-VMCLogicalNetwork { $logicalNetworkService.create($orgId, $sddcId, $logicalNetworkSpec) Get-VMCLogicalNetwork -OrgName $OrgName -SDDCName $SDDCName -LogicalNetworkName $LogicalNetworkName } - Function Get-VMCSDDCSummary { <# .NOTES @@ -899,7 +899,6 @@ Function Get-VMCSDDCSummary { $results } } - Function Get-VMCPublicIP { <# .NOTES @@ -933,79 +932,377 @@ Function Get-VMCPublicIP { $publicIPs | select public_ip, name, allocation_id } } +Function New-VMCPublicIP { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/12/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== - Function New-VMCPublicIP { - <# - .NOTES - =========================================================================== - Created by: William Lam - Date: 09/12/2018 - Organization: VMware - Blog: http://www.virtuallyghetto.com - Twitter: @lamw - =========================================================================== + .SYNOPSIS + Request a new public IP Address for a given SDDC + .DESCRIPTION + This cmdlet requests a new public IP Address for a given SDDC + .EXAMPLE + New-VMCPublicIP -OrgName $OrgName -SDDCName $SDDCName -Description "Test for Randy" +#> + Param ( + [Parameter(Mandatory=$True)]$OrgName, + [Parameter(Mandatory=$True)]$SDDCName, + [Parameter(Mandatory=$False)]$Description + ) - .SYNOPSIS - Request a new public IP Address for a given SDDC - .DESCRIPTION - This cmdlet requests a new public IP Address for a given SDDC - .EXAMPLE - New-VMCPublicIP -OrgName $OrgName -SDDCName $SDDCName -Description "Test for Randy" - #> - Param ( - [Parameter(Mandatory=$True)]$OrgName, - [Parameter(Mandatory=$True)]$SDDCName, - [Parameter(Mandatory=$False)]$Description - ) + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id - If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { - $orgId = (Get-VMCOrg -Name $OrgName).Id - $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $publicIPService = Get-VmcService "com.vmware.vmc.orgs.sddcs.publicips" - $publicIPService = Get-VmcService "com.vmware.vmc.orgs.sddcs.publicips" + $publicIPSpec = $publicIPService.Help.create.spec.Create() + $publicIPSpec.count = 1 + $publicIPSpec.names = @($Description) - $publicIPSpec = $publicIPService.Help.create.spec.Create() - $publicIPSpec.count = 1 - $publicIPSpec.names = @($Description) + Write-Host "Requesting a new public IP Address for your SDDC ..." + $results = $publicIPService.create($orgId,$sddcId,$publicIPSpec) + } +} +Function Remove-VMCPublicIP { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/12/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== - Write-Host "Requesting a new public IP Address for your SDDC ..." - $results = $publicIPService.create($orgId,$sddcId,$publicIPSpec) + .SYNOPSIS + Removes a specific public IP Addresses for a given SDDC + .DESCRIPTION + This cmdlet removes a specific public IP Address for a given SDDC + .EXAMPLE + Remove-VMCPublicIP -OrgName $OrgName -SDDCName $SDDCName -AllocationId "eipalloc-0567acf34e436c01f" +#> + Param ( + [Parameter(Mandatory=$True)]$OrgName, + [Parameter(Mandatory=$True)]$SDDCName, + [Parameter(Mandatory=$True)]$AllocationId + ) + + If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + + $publicIPService = Get-VmcService "com.vmware.vmc.orgs.sddcs.publicips" + + Write-Host "Deleting public IP Address with ID $AllocationId ..." + $results = $publicIPService.delete($orgId,$sddcId,$AllocationId) + } +} +Function Get-VMCEdge { +<# +.NOTES +=========================================================================== +Created by: Luc Dekens +Date: 23/10/2018 +Organization: Community +Blog: http://lucd.info +Twitter: @LucD22 +=========================================================================== + +.SYNOPSIS + Returns all the VMC Edges +.DESCRIPTION + Returns all the VMC Edges +.EXAMPLE + Get-VMCEdge -OrgName $orgName -SddcName $SDDCName -EdgeType gatewayServices +#> + Param ( + [Parameter(Mandatory=$True)] + [string]$OrgName, + [Parameter(Mandatory=$True)] + [string]$SDDCName, + [ValidateSet('gatewayServices','distributedRouter')] + [string]$EdgeType = '' + ) + + If (-Not $global:DefaultVMCServers) { + Write-error "No VMC Connection found, please use the Connect-VMC to connect" + } + Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + + $edgeService = Get-VmcService -Name 'com.vmware.vmc.orgs.sddcs.networks.edges' + $index = [long]0 + $edges = do{ + $edgeData = $edgeService.get($orgId,$sddcId,$EdgeType,'',$index) + $edgeData.edge_page.data | Sort-Object -Property id + $index = $index + $edgeData.edge_page.paging_info.page_size + } + until($index -ge $edgeData.paging_info.total_count) + $edges | %{ + [pscustomobject]@{ + Name = $_.Name + Id = $_.id + Type = $_.edge_type + State = $_.state + Status = $_.edge_status + VNics = $_.number_of_connected_vnics + TenantId = $_.tenant_id + } } } +} +Function Get-VMCEdgeStatus { +<# +.NOTES +=========================================================================== +Created by: Luc Dekens +Date: 23/10/2018 +Organization: Community +Blog: http://lucd.info +Twitter: @LucD22 +=========================================================================== - Function Remove-VMCPublicIP { - <# - .NOTES - =========================================================================== - Created by: William Lam - Date: 09/12/2018 - Organization: VMware - Blog: http://www.virtuallyghetto.com - Twitter: @lamw - =========================================================================== +.SYNOPSIS + Returns the status of the gateway +.DESCRIPTION + Retrieve the status of the specified management or compute gateway (NSX Edge). +.EXAMPLE + Get-VMCEdgeStatus -OrgName $orgName -SddcName $SDDCName -Edge $EdgeName +#> + Param ( + [Parameter(Mandatory=$True)] + [string]$OrgName, + [Parameter(Mandatory=$True)] + [string]$SDDCName, + [Parameter(Mandatory=$True)] + [string]$EdgeName + ) - .SYNOPSIS - Removes a specific public IP Addresses for a given SDDC - .DESCRIPTION - This cmdlet removes a specific public IP Address for a given SDDC - .EXAMPLE - Remove-VMCPublicIP -OrgName $OrgName -SDDCName $SDDCName -AllocationId "eipalloc-0567acf34e436c01f" - #> - Param ( - [Parameter(Mandatory=$True)]$OrgName, - [Parameter(Mandatory=$True)]$SDDCName, - [Parameter(Mandatory=$True)]$AllocationId - ) + If (-Not $global:DefaultVMCServers) { + Write-error "No VMC Connection found, please use the Connect-VMC to connect" + } + Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $edgeId = Get-VMCEdge -SDDCName $SDDCName -Org $OrgName | where{$_.Name -eq $EdgeName} | select -ExpandProperty Id - If (-Not $global:DefaultVMCServers) { Write-error "No VMC Connection found, please use the Connect-VMC to connect" } Else { - $orgId = (Get-VMCOrg -Name $OrgName).Id - $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $statusService = Get-VmcService -Name 'com.vmware.vmc.orgs.sddcs.networks.edges.status' + $status = $statusService.get($orgId,$sddcId,$edgeId) - $publicIPService = Get-VmcService "com.vmware.vmc.orgs.sddcs.publicips" - - Write-Host "Deleting public IP Address with ID $AllocationId ..." - $results = $publicIPService.delete($orgId,$sddcId,$AllocationId) + $vmStatus = $status.edge_vm_status | %{ + [pscustomobject]@{ + Name = $_.name + State = $_.edge_VM_status + HAState = $_.ha_state + Index = $_.index + } + } + $featureStatus = $status.feature_statuses | %{ + [pscustomobject]@{ + Service = $_.service + Status = $_.status + } + } + [pscustomobject]@{ + Time = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($status.timestamp/1000)) + Status = $status.edge_status + PublishStatus = $status.publish_status + SystemStatus = $_.system_status + NicInUse = $status.ha_vnic_in_use } } +} +Function Get-VMCEdgeNic { +<# +.NOTES +=========================================================================== +Created by: Luc Dekens +Date: 23/10/2018 +Organization: Community +Blog: http://lucd.info +Twitter: @LucD22 +=========================================================================== -Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork', 'Get-VMCSDDCSummary', 'Get-VMCPublicIP', 'New-VMCPublicIP', 'Remove-VMCPublicIP' +.SYNOPSIS + Returns all interfaces for the gateway +.DESCRIPTION + Retrieve all interfaces for the specified management or compute gateway (NSX Edge). +.EXAMPLE + Get-VMCEdgeNic -OrgName $orgName -SddcName $SDDCName -Edge $EdgeName +#> + Param ( + [Parameter(Mandatory=$True)] + [string]$OrgName, + [Parameter(Mandatory=$True)] + [string]$SDDCName, + [Parameter(Mandatory=$True)] + [string]$EdgeName + ) + + If (-Not $global:DefaultVMCServers) { + Write-error "No VMC Connection found, please use the Connect-VMC to connect" + } + Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $edgeId = Get-VMCEdge -SDDCName $SDDCName -Org $OrgName | where{$_.Name -eq $EdgeName} | select -ExpandProperty Id + + $vnicService = Get-VmcService -Name 'com.vmware.vmc.orgs.sddcs.networks.edges.vnics' + $vnicService.get($orgId,$sddcId,$edgeId) | select -ExpandProperty vnics | %{ + [pscustomobject]@{ + Label = $_.label + Name = $_.Name + Type = $_.type + Index = $_.index + IsConnected = $_.is_connected + Portgroup = $_.portgroup_name + } + } + } +} +Function Get-VMCEdgeNicStat { +<# +.NOTES +=========================================================================== +Created by: Luc Dekens +Date: 23/10/2018 +Organization: Community +Blog: http://lucd.info +Twitter: @LucD22 +=========================================================================== + +.SYNOPSIS + Returns statistics for the gateway interfaces +.DESCRIPTION + Retrieve interface statistics for a management or compute gateway (NSX Edge). +.EXAMPLE + Get-VMCEdgeNicStat -OrgName $orgName -SddcName $SDDCName -Edge $EdgeName +#> + [CmdletBinding(DefaultParameterSetName='Default')] + Param ( + [Parameter(Mandatory=$True)] + [string]$OrgName, + [Parameter(Mandatory=$True)] + [string]$SDDCName, + [Parameter(Mandatory=$True)] + [string]$EdgeName +# [DateTime]$Start, +# [DateTime]$Finish + ) + + If (-Not $global:DefaultVMCServers) { + Write-error "No VMC Connection found, please use the Connect-VMC to connect" + } + Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $edgeId = Get-VMCEdge -SDDCName $SDDCName -Org $OrgName | where{$_.Name -eq $EdgeName} | select -ExpandProperty Id + +# $epoch = Get-Date 01/01/1970 +# +# if($start){ +# $startEpoch = (New-TimeSpan -Start $epoch -End $Start.ToUniversalTime()).TotalMilliseconds +# } +# if($Finish){ +# $finishEpoch = (New-TimeSpan -Start $epoch -End $Finish.ToUniversalTime()).TotalMilliseconds +# } + + $vnicStatService = Get-VmcService -Name 'com.vmware.vmc.orgs.sddcs.networks.edges.statistics.interfaces' +# $stats = $vnicStatService.get($orgId,$sddcId,$edgeId,[long]$startEpoch,[long]$finishEpoch) + $stats = $vnicStatService.get($orgId,$sddcId,$edgeId) + + $stats.data_dto | Get-Member -MemberType NoteProperty | where{$_.Name -ne 'Help'} | %{$_.Name} | %{ + $stats.data_dto."$_" | %{ + [pscustomobject]@{ + vNIC = $_.vnic + Timestamp = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($_.timestamp)) + In = $_.in + Out = $_.out + Unit = 'Kbps' + Interval = $stats.meta_dto.interval + } + } + } + } +} +Function Get-VMCEdgeUplinkStat { +<# +.NOTES +=========================================================================== +Created by: Luc Dekens +Date: 23/10/2018 +Organization: Community +Blog: http://lucd.info +Twitter: @LucD22 +=========================================================================== + +.SYNOPSIS + Returns statistics for the uplink interfaces +.DESCRIPTION + Retrieve uplink interface statistics for a management or compute gateway (NSX Edge). +.EXAMPLE + Get-VMCEdgeUplinkStat -OrgName $orgName -SddcName $SDDCName -Edge $EdgeName +#> + Param ( + [Parameter(Mandatory=$True)] + [string]$OrgName, + [Parameter(Mandatory=$True)] + [string]$SDDCName, + [Parameter(Mandatory=$True)] + [string]$EdgeName +# [DateTime]$Start, +# [DateTime]$Finish + ) + + If (-Not $global:DefaultVMCServers) { + Write-error "No VMC Connection found, please use the Connect-VMC to connect" + } + Else { + $orgId = (Get-VMCOrg -Name $OrgName).Id + $sddcId = (Get-VMCSDDC -Name $SDDCName -Org $OrgName).Id + $edgeId = Get-VMCEdge -SDDCName $SDDCName -Org $OrgName | where{$_.Name -eq $EdgeName} | select -ExpandProperty Id + +# $epoch = Get-Date 01/01/1970 +# +# if($start){ +# $startEpoch = (New-TimeSpan -Start $epoch -End $Start.ToUniversalTime()).TotalMilliseconds +# } +# if($Finish){ +# $finishEpoch = (New-TimeSpan -Start $epoch -End $Finish.ToUniversalTime()).TotalMilliseconds +# } + + $uplinkStatService = Get-VmcService -Name 'com.vmware.vmc.orgs.sddcs.networks.edges.statistics.interfaces.uplink' +# $stats = $uplinkStatService.get($orgId,$sddcId,$edgeId,[long]$startEpoch,[long]$finishEpoch) + $stats = $uplinkStatService.get($orgId,$sddcId,$edgeId) + + $stats.data_dto | Get-Member -MemberType NoteProperty | where{$_.Name -ne 'Help'} | %{$_.Name} | %{ + if($stats.data_dto."$_".Count -ne 0){ + $stats.data_dto."$_" | %{ + [pscustomobject]@{ + vNIC = $_.vnic + Timestamp = [timezone]::CurrentTimeZone.ToLocalTime(([datetime]'1/1/1970').AddSeconds($_.timestamp)) + In = $_.in + Out = $_.out + Unit = 'Kbps' + Interval = $stats.meta_dto.interval + } + } + } + } + } +} + +Export-ModuleMember -Function 'Get-VMCCommand', 'Connect-VMCVIServer', 'Get-VMCOrg', 'Get-VMCSDDC', + 'Get-VMCTask', 'Get-VMCSDDCDefaultCredential', 'Get-VMCSDDCPublicIP', 'Get-VMCVMHost', + 'Get-VMCSDDCVersion', 'Get-VMCFirewallRule', 'Export-VMCFirewallRule', 'Import-VMCFirewallRule', + 'Remove-VMCFirewallRule', 'Get-VMCLogicalNetwork', 'Remove-VMCLogicalNetwork', 'New-VMCLogicalNetwork', + 'Get-VMCSDDCSummary', 'Get-VMCPublicIP', 'New-VMCPublicIP', 'Remove-VMCPublicIP', + 'Get-VMCEdge', 'Get-VMCEdgeNic', 'Get-VMCEdgeStatus', 'Get-VMCEdgeNicStat', 'Get-VMCEdgeUplinkStat' From 3904b416b3ddd74827374735911d286437890997 Mon Sep 17 00:00:00 2001 From: LucD Date: Thu, 25 Oct 2018 10:43:04 +0200 Subject: [PATCH 49/50] XRef for VMC services and functions Requires ImportExcel module --- .../VMware_Cloud_on_AWS/XRef-VMC-Services.ps1 | 37 +++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 Scripts/VMware_Cloud_on_AWS/XRef-VMC-Services.ps1 diff --git a/Scripts/VMware_Cloud_on_AWS/XRef-VMC-Services.ps1 b/Scripts/VMware_Cloud_on_AWS/XRef-VMC-Services.ps1 new file mode 100644 index 0000000..eb591bb --- /dev/null +++ b/Scripts/VMware_Cloud_on_AWS/XRef-VMC-Services.ps1 @@ -0,0 +1,37 @@ +$refreshToken = 'your-refresh-token' + +$reportPath = '.\VMC-services.xlsx' + +Connect-Vmc -RefreshToken $refreshToken > $null + +$columns = @{} +$services = Get-VmcService | Sort-Object -Property Name +$services | ForEach-Object -Process { + $_.Help | Get-Member -MemberType NoteProperty | where{'Constants','Documentation' -notcontains $_.Name} | + ForEach-Object -Process { + if(-not $columns.ContainsKey($_.Name)){ + $columns.Add($_.Name,'') + } + } +} +$columns = $columns.Keys | Sort-Object +$report = @() +foreach($service in $services){ + $obj = [ordered]@{ + Name = $service.Name + } + $columns | ForEach-Object -Process { + $obj.Add($_,'') + } + + $service.Help | Get-Member -MemberType NoteProperty | where{'Constants','Documentation' -notcontains $_.Name} | + ForEach-Object -Process { +# $obj.Item($_.Name) = "$($service.Help.$($_.Name).Documentation)" + $obj.Item($_.Name) = "X" + } + $report += New-Object PSObject -Property $obj +} +$report | Export-Excel -Path $reportPath -WorksheetName 'Services' -FreezeTopRow -BoldTopRow -AutoSize -Show + +Disconnect-Vmc -Confirm:$false + From 578d3c5deb27e3a945a6a12112d8a266e3491161 Mon Sep 17 00:00:00 2001 From: William Lam Date: Thu, 1 Nov 2018 07:33:40 -0700 Subject: [PATCH 50/50] Updated to include configuringn Proxy Settings --- Modules/VMware.HCX/VMware.HCX.psd1 | 2 +- Modules/VMware.HCX/VMware.HCX.psm1 | 298 ++++++++++++++++++++++------- 2 files changed, 233 insertions(+), 67 deletions(-) diff --git a/Modules/VMware.HCX/VMware.HCX.psd1 b/Modules/VMware.HCX/VMware.HCX.psd1 index 4e1e68b..a5e74f0 100644 --- a/Modules/VMware.HCX/VMware.HCX.psd1 +++ b/Modules/VMware.HCX/VMware.HCX.psd1 @@ -36,7 +36,7 @@ Description = 'PowerShell Module for Managing Hybrid Cloud Extension (HCX) on VM PowerShellVersion = '6.0' # Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export. -FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI', 'Get-HcxVCConfig', 'Set-HcxLicense', 'Set-HcxVCConfig', 'Get-HcxNSXConfig', 'Set-HcxNSXConfig', 'Get-HcxCity', 'Get-HcxLocation', 'Set-HcxLocation', 'Get-HcxRoleMapping', 'Set-HcxRoleMapping' +FunctionsToExport = 'Connect-HcxServer', 'Get-HcxCloudConfig', 'Get-HcxEndpoint', 'New-HcxMigration', 'Get-HcxMigration', 'Connect-HcxVAMI', 'Get-HcxVCConfig', 'Set-HcxLicense', 'Set-HcxVCConfig', 'Get-HcxNSXConfig', 'Set-HcxNSXConfig', 'Get-HcxCity', 'Get-HcxLocation', 'Set-HcxLocation', 'Get-HcxRoleMapping', 'Set-HcxRoleMapping', 'Get-HcxProxy', 'Set-HcxProxy', 'Remove-HcxProxy' # Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export. CmdletsToExport = @() diff --git a/Modules/VMware.HCX/VMware.HCX.psm1 b/Modules/VMware.HCX/VMware.HCX.psm1 index 7e5093c..cfbe95b 100644 --- a/Modules/VMware.HCX/VMware.HCX.psm1 +++ b/Modules/VMware.HCX/VMware.HCX.psm1 @@ -1047,87 +1047,250 @@ Function Set-HcxLocation { } } Function Get-HcxRoleMapping { - <# - .NOTES - =========================================================================== - Created by: William Lam - Date: 09/16/2018 - Organization: VMware - Blog: http://www.virtuallyghetto.com - Twitter: @lamw - =========================================================================== +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== - .SYNOPSIS - Returns the System Admin and Enterprise User Group role mappings for HCX Manager - .DESCRIPTION - This cmdlet returns the System Admin and Enterprise User Group role mappings for HCX Manager - .EXAMPLE - Get-HcxRoleMapping - #> - If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { - $roleConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/roleMappings" + .SYNOPSIS + Returns the System Admin and Enterprise User Group role mappings for HCX Manager + .DESCRIPTION + This cmdlet returns the System Admin and Enterprise User Group role mappings for HCX Manager + .EXAMPLE + Get-HcxRoleMapping +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $roleConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/roleMappings" + if($PSVersionTable.PSEdition -eq "Core") { + $roleRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $roleRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + ($roleRequests.content | ConvertFrom-Json) + } +} + +Function Set-HcxRoleMapping { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 09/16/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Configures the System Admin and Enterprise User Group role mappings for HCX Manager + .DESCRIPTION + This cmdlet configures the System Admin and Enterprise User Group role mappings for HCX Manager + .EXAMPLE + Set-HcxRoleMapping -SystemAdminGroup @("DOMAIN\GROUP") -EnterpriseAdminGroup @("DOMAIN\GROUP") +#> + Param ( + [Parameter(Mandatory=$True)][String[]]$SystemAdminGroup, + [Parameter(Mandatory=$True)][String[]]$EnterpriseAdminGroup, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $roleConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/roleMappings" + $method = "PUT" + + $roleConfig = @() + $systemAdminRole = @{ + role = "System Administrator"; + userGroups = $SystemAdminGroup + } + $enterpriseAdminRole = @{ + role = "Enterprise Administrator" + userGroups = $EnterpriseAdminGroup + } + $roleConfig+=$systemAdminRole + $roleConfig+=$enterpriseAdminRole + + $body = $roleConfig | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$locationConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { if($PSVersionTable.PSEdition -eq "Core") { - $roleRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + $results = Invoke-WebRequest -Uri $roleConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck } else { - $roleRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + $results = Invoke-WebRequest -Uri $roleConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing } - ($roleRequests.content | ConvertFrom-Json) + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully updated vSphere Group Mappings in HCX Manager" + } else { + Write-Error "Failed to update vSphere Group Mappings" } } +} - Function Set-HcxRoleMapping { - <# - .NOTES - =========================================================================== - Created by: William Lam - Date: 09/16/2018 - Organization: VMware - Blog: http://www.virtuallyghetto.com - Twitter: @lamw - =========================================================================== +Function Get-HcxProxy { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 10/31/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== - .SYNOPSIS - Configures the System Admin and Enterprise User Group role mappings for HCX Manager - .DESCRIPTION - This cmdlet configures the System Admin and Enterprise User Group role mappings for HCX Manager - .EXAMPLE - Set-HcxRoleMapping -SystemAdminGroup @("DOMAIN\GROUP") -EnterpriseAdminGroup @("DOMAIN\GROUP") - #> - Param ( - [Parameter(Mandatory=$True)][String[]]$SystemAdminGroup, - [Parameter(Mandatory=$True)][String[]]$EnterpriseAdminGroup, - [Switch]$Troubleshoot - ) + .SYNOPSIS + Returns the proxy settings for HCX Manager + .DESCRIPTION + This cmdlet returns the proxy settings for HCX Manager + .EXAMPLE + Get-HcxProxy +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $proxyConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/proxy" - If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { - $roleConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/roleMappings" - $method = "PUT" + if($PSVersionTable.PSEdition -eq "Core") { + $proxyRequests = Invoke-WebRequest -Uri $proxyConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $proxyRequests = Invoke-WebRequest -Uri $proxyConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + $proxySettings = ($proxyRequests.content | ConvertFrom-Json).data.items + if($proxyRequests) { + $proxySettings.config + } + } +} - $roleConfig = @() - $systemAdminRole = @{ - role = "System Administrator"; - userGroups = $SystemAdminGroup +Function Set-HcxProxy { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 10/31/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Configure proxy settings on HCX Manager + .DESCRIPTION + This cmdlet configure proxy settings on HCX Manager + .EXAMPLE + Set-HcxProxy -ProxyServer proxy.vmware.com -ProxyPort 3124 + .EXAMPLE + Set-HcxProxy -ProxyServer proxy.vmware.com -ProxyPort 3124 -ProxyUser foo -ProxyPassword bar +#> + Param ( + [Parameter(Mandatory=$True)]$ProxyServer, + [Parameter(Mandatory=$True)]$ProxyPort, + [Parameter(Mandatory=$False)]$ProxyUser, + [Parameter(Mandatory=$False)]$ProxyPassword, + [Switch]$Troubleshoot + ) + + If (-Not $global:hcxVAMIConnection) { Write-error "HCX VAMI Auth Token not found, please run Connect-HcxVAMI " } Else { + $proxyConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/proxy" + $method = "POST" + + if(-not $ProxyUser) { $ProxyUser = ""} + if(-not $ProxyPassword) { $ProxyPassword = ""} + + $proxyConfig = @{ + config = @{ + proxyHost = "$ProxyServer"; + proxyPort = "$ProxyPort"; + nonProxyHosts = ""; + userName = "$ProxyUser"; + password = "$ProxyPassword"; } - $enterpriseAdminRole = @{ - role = "Enterprise Administrator" - userGroups = $EnterpriseAdminGroup - } - $roleConfig+=$systemAdminRole - $roleConfig+=$enterpriseAdminRole + } - $body = $roleConfig | ConvertTo-Json -Depth 5 - - if($Troubleshoot) { - Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$locationConfigUrl`n" - Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + $payload = @{ + data = @{ + items = @($proxyConfig) } + } + + $body = $payload | ConvertTo-Json -Depth 5 + + if($Troubleshoot) { + Write-Host -ForegroundColor cyan "`n[DEBUG] - $method`n$proxyConfigUrl`n" + Write-Host -ForegroundColor cyan "[DEBUG]`n$body`n" + } + + try { + if($PSVersionTable.PSEdition -eq "Core") { + $results = Invoke-WebRequest -Uri $proxyConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $results = Invoke-WebRequest -Uri $proxyConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + } catch { + Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" + break + } + + if($results.StatusCode -eq 200) { + Write-Host -ForegroundColor Green "Successfully updated proxy settings in HCX Manager" + if($Troubleshoot) { ($results.Content | ConvertFrom-Json).data.items.config } + } else { + Write-Error "Failed to update proxy settings" + } + } +} + +Function Remove-HcxProxy { +<# + .NOTES + =========================================================================== + Created by: William Lam + Date: 10/31/2018 + Organization: VMware + Blog: http://www.virtuallyghetto.com + Twitter: @lamw + =========================================================================== + + .SYNOPSIS + Returns the proxy settings for HCX Manager + .DESCRIPTION + This cmdlet returns the proxy settings for HCX Manager + .EXAMPLE + Remove-HcxProxy +#> + If (-Not $global:hcxVAMIConnection) { Write-error "HCX Auth Token not found, please run Connect-HcxVAMI " } Else { + $roleConfigUrl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/proxy" + + if($PSVersionTable.PSEdition -eq "Core") { + $proxyRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + } else { + $proxyRequests = Invoke-WebRequest -Uri $roleConfigUrl -Method GET -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + } + $proxySettings = ($proxyRequests.content | ConvertFrom-Json).data.items + if($proxyRequests) { + $proxyUUID = $proxySettings.config.UUID + + $deleteProxyConfigURl = $global:hcxVAMIConnection.Server + "/api/admin/global/config/proxy/$proxyUUID" + $method = "DELETE" try { if($PSVersionTable.PSEdition -eq "Core") { - $results = Invoke-WebRequest -Uri $roleConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck + $results = Invoke-WebRequest -Uri $deleteProxyConfigURl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing -SkipCertificateCheck } else { - $results = Invoke-WebRequest -Uri $roleConfigUrl -Body $body -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing + $results = Invoke-WebRequest -Uri $deleteProxyConfigURl -Method $method -Headers $global:hcxVAMIConnection.headers -UseBasicParsing } } catch { Write-Host -ForegroundColor Red "`nRequest failed: ($_.Exception)`n" @@ -1135,9 +1298,12 @@ Function Get-HcxRoleMapping { } if($results.StatusCode -eq 200) { - Write-Host -ForegroundColor Green "Successfully updated vSphere Group Mappings in HCX Manager" + Write-Host -ForegroundColor Green "Successfully deleted proxy settings in HCX Manager" } else { - Write-Error "Failed to update vSphere Group Mappings" + Write-Error "Failed to delete proxy settings" } + } else { + Write-Warning "No proxy settings were configured" } - } \ No newline at end of file + } +} \ No newline at end of file