From b49b3f9430c9dcc973160994f9771a920bebc629 Mon Sep 17 00:00:00 2001 From: Kyle Ruddy Date: Thu, 8 Dec 2016 11:49:49 -0500 Subject: [PATCH 01/11] Update DatastoreSIOCStatistics.ps1 --- Scripts/DatastoreSIOCStatistics.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Scripts/DatastoreSIOCStatistics.ps1 b/Scripts/DatastoreSIOCStatistics.ps1 index a407506..0121b07 100644 --- a/Scripts/DatastoreSIOCStatistics.ps1 +++ b/Scripts/DatastoreSIOCStatistics.ps1 @@ -58,7 +58,7 @@ function Set-DatastoreSIOCStatCollection { .PARAMETER Datastore Datastore to be ran against .EXAMPLE - Set-DatastoreSIOCStatCollection -Datastore ExampleDatastore -Enable $true + Set-DatastoreSIOCStatCollection -Datastore ExampleDatastore -Enable Enables SIOC statistics collection for the provided datastore #> [CmdletBinding(SupportsShouldProcess)] @@ -105,4 +105,4 @@ function Set-DatastoreSIOCStatCollection { } } -} \ No newline at end of file +} From 1977251e8fe9dca2a14f413760e558df47e7e5c0 Mon Sep 17 00:00:00 2001 From: baoyinqiao Date: Fri, 9 Dec 2016 15:31:03 +0800 Subject: [PATCH 02/11] Add a VMEncryption module Add a module which include VMEncryption related functions/cmdlets. --- Modules/VMware.VMEncryption/README.md | 7 + .../VMware.VMEncryption.psd1 | Bin 0 -> 5090 bytes .../VMware.VMEncryption.psm1 | 2045 +++++++++++++++++ 3 files changed, 2052 insertions(+) create mode 100644 Modules/VMware.VMEncryption/README.md create mode 100644 Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 create mode 100644 Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 diff --git a/Modules/VMware.VMEncryption/README.md b/Modules/VMware.VMEncryption/README.md new file mode 100644 index 0000000..9e38900 --- /dev/null +++ b/Modules/VMware.VMEncryption/README.md @@ -0,0 +1,7 @@ +Prerequisites/Steps to use this module: + +1. This module only works for vSphere products that support VM Encryption. E.g. vSphere 6.5 and later. +2. All the functions in this module only work for KMIP Servers. +3. Install the latest version of Powershell and PowerCLI(6.5). +4. Import this module by running: Import-Module -Name "location of this module" +5. Get-Command -Module "This module Name" to list all available functions. \ No newline at end of file diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 new file mode 100644 index 0000000000000000000000000000000000000000..d3106326576f014d290d1010af53ab6bbfbeac3c GIT binary patch literal 5090 zcmcgwTTc^F5T57$icNSZ8mWS)U}7TSA|!yMBKq2HFK+D3(pru2udClT)5AHZ+rrXR z(zLsK_RP#T_c{IhXH817CW)L$Um7x&jx_Pqm74SYJ~-Z*?vM42L@cA*ZYR~<-us>jcqmMy$9yVPKfYfz_H@#rUb8p#*X z@i)Vcyag*$BvnxNu`jmw8&H(hN{07J?Q;!Y)HA_%4Aga9O|aIQk>&NFoRIe{CzG@Z zUp))toyY+=j)C0#F@g*}GX}ol+JyeJO9pSzd-Q8dS3-?FijusOk78U+VhcWcf$tXR zw`E5*;Hebcp5tyC>)Tl0!1^wHSjSxxpG{!obr-T;sdsk*%zMB^>E^%NY*LbVuOSL! zjqz!g-v_@g;)L-}jg9+vpy&Z@5m_;Zb8zZ{I+488Cs;iJ-xS`65ey)E2phMdAG41+ zXz@l~w7<{DMIIoISw4ng-kWuxcm%F4i{e}iktVQa2cINB$cSeJVEhb))@npL9q2n& z1a?SzUarLv?_k5kJPY4f%|D_7CQ=)xUMwms6=~m02dfjQTDeE+CivnYDtR%je69_epXYfORS=_Qcpc&-Gud(^^W#3`j9udw)Ksl zZ#+ipoK;8*Yg{;mPz!4L78ZYW(`)zCM@^up16v0A+qI=0HTcD5l+`1ik0*~io+jON zNbKwAdIM;&sd3}|X7jPj3Hpswo%2wtzTt#9#2i3A>>jK3lAAz7^w+39eRQxeXXbh8 z5`XT#K$cY*qMqI2C zKaQqxb^_++NNvBI?0q2fT#CrOg0ESTYg!v!Wn^yMSMNNhBJw%oQ#vR5!MF3TQ&8aalB9eC;l zdB^{c68tAn#gp^xqD-ZXSz1RqD}!ge77*~CD@F~c09=^4%;R&99Y(_$Q)+T09vf>?Gl+eTDj6a4Q%+dBL%Vq+b7dgt72x`g}P Me+=e<-#Tag10n%j>;M1& literal 0 HcmV?d00001 diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 new file mode 100644 index 0000000..149fd49 --- /dev/null +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 @@ -0,0 +1,2045 @@ +# Script Module : VMware.VMEncryption +# Version : 1.0 + +# 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) + ($vm.extensiondata.Runtime.ConnectionState -eq "invalid") -and ($vm.extensiondata.Config.KeyId) +} -BasedOnExtensionProperty 'Runtime.ConnectionState','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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 { + # 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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True)] + [String]$KMSClusterId, + + [Parameter(Mandatory=$True)] + [String]$Name + ) + + Begin { + # 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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + # 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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 { + # 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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 { + # 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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + # 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 + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + + #> + + [CmdLetBinding()] + + Param ( + [Parameter(Mandatory=$True)] + [String] $KMSClusterId + ) + + # 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 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}!" + } +} + +Export-ModuleMember *-* From 554f6d691d7c2d461465e0c72f4d4ae033b313d8 Mon Sep 17 00:00:00 2001 From: praveenmathamsetty Date: Tue, 13 Dec 2016 17:20:51 +0530 Subject: [PATCH 03/11] Get-HVMachine, Get-HVMachineSummary changes Adding new advanced functions Get-HVMachine and Get-HVMachineSummary. Queries and returns virtual machines information, the machines list would be determined based on queryable fields poolName, dnsName, machineName, state. When more than one fields are used for query the virtual machines which satisfy all fields criteria would be returned. --- .../VMware.Hv.Helper/VMware.HV.Helper.psm1 | 347 +++++++++++++++++- 1 file changed, 330 insertions(+), 17 deletions(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index 6884703..2a8b70a 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -242,7 +242,7 @@ The Add-HVDesktop adds virtual machines to already exiting pools by using view A try { $desktopPool = Get-HVPoolSummary -poolName $poolName -hvServer $hvServer } catch { - Write-Error "Make sure Get-HVPool advanced function is loaded, $_" + Write-Error "Make sure Get-HVPoolSummary advanced function is loaded, $_" break } if ($desktopPool) { @@ -1087,7 +1087,7 @@ function Find-HVFarm { 'farmType' = 'data.type'; } - $parms = $Param + $params = $Param $query_service_helper = New-Object VMware.Hv.QueryServiceService $query = New-Object VMware.Hv.QueryDefinition @@ -1097,10 +1097,10 @@ function Find-HVFarm { $query.queryEntityType = 'FarmSummaryView' [VMware.Hv.queryfilter[]]$filterSet = @() foreach ($setting in $farmSelectors.Keys) { - if ($null -ne $parms[$setting]) { + if ($null -ne $params[$setting]) { $equalsFilter = New-Object VMware.Hv.QueryFilterEquals $equalsFilter.memberName = $farmSelectors[$setting] - $equalsFilter.value = $parms[$setting] + $equalsFilter.value = $params[$setting] $filterSet += $equalsFilter } } @@ -1370,17 +1370,17 @@ function Find-HVPool { 'provisioningEnabled' = 'desktopSummaryData.provisioningEnabled' } - $parms = $Param + $params = $Param $query_service_helper = New-Object VMware.Hv.QueryServiceService $query = New-Object VMware.Hv.QueryDefinition $wildCard = $false #Only supports wild card '*' - if ($parms['PoolName'] -and $parms['PoolName'].contains('*')) { + if ($params['PoolName'] -and $params['PoolName'].contains('*')) { $wildcard = $true } - if ($parms['PoolDisplayName'] -and $parms['PoolDisplayName'].contains('*')) { + if ($params['PoolDisplayName'] -and $params['PoolDisplayName'].contains('*')) { $wildcard = $true } # build the query values @@ -1388,10 +1388,10 @@ function Find-HVPool { if (! $wildcard) { [VMware.Hv.queryfilter[]]$filterSet = @() foreach ($setting in $poolSelectors.Keys) { - if ($null -ne $parms[$setting]) { + if ($null -ne $params[$setting]) { $equalsFilter = New-Object VMware.Hv.QueryFilterEquals $equalsFilter.memberName = $poolSelectors[$setting] - $equalsFilter.value = $parms[$setting] + $equalsFilter.value = $params[$setting] $filterSet += $equalsFilter } } @@ -1408,11 +1408,11 @@ function Find-HVPool { $queryResults = $query_service_helper.QueryService_Query($services,$query) $strFilterSet = @() foreach ($setting in $poolSelectors.Keys) { - if ($null -ne $parms[$setting]) { + if ($null -ne $params[$setting]) { if ($wildcard -and (($setting -eq 'PoolName') -or ($setting -eq 'PoolDisplayName')) ) { - $strFilterSet += '($_.' + $poolSelectors[$setting] + ' -like "' + $parms[$setting] + '")' + $strFilterSet += '($_.' + $poolSelectors[$setting] + ' -like "' + $params[$setting] + '")' } else { - $strFilterSet += '($_.' + $poolSelectors[$setting] + ' -eq "' + $parms[$setting] + '")' + $strFilterSet += '($_.' + $poolSelectors[$setting] + ' -eq "' + $params[$setting] + '")' } } } @@ -3062,7 +3062,7 @@ function New-HVPool { try { $sourcePool = Get-HVPoolSummary -poolName $poolName -hvServer $hvServer } catch { - Write-Error "Make sure Get-HVPool advanced function is loaded, $_" + Write-Error "Make sure Get-HVPoolSummary advanced function is loaded, $_" break } if ($sourcePool) { @@ -3888,7 +3888,7 @@ function Remove-HVPool { try { $myPools = Get-HVPoolSummary -poolName $poolName -hvServer $hvServer } catch { - Write-Error "Make sure Get-HVPool advanced function is loaded, $_" + Write-Error "Make sure Get-HVPoolSummary advanced function is loaded, $_" break } if ($myPools) { @@ -4258,7 +4258,7 @@ function Set-HVPool { try { $desktopPools = Get-HVPoolSummary -poolName $poolName -hvServer $hvServer } catch { - Write-Error "Make sure Get-HVPool advanced function is loaded, $_" + Write-Error "Make sure Get-HVPoolSummary advanced function is loaded, $_" break } if ($desktopPools) { @@ -4767,7 +4767,7 @@ function Start-HVPool { try { $poolObj = Get-HVPoolSummary -poolName $item -hvServer $hvServer } catch { - Write-Error "Make sure Get-HVPool advanced function is loaded, $_" + Write-Error "Make sure Get-HVPoolSummary advanced function is loaded, $_" break } if ($poolObj) { @@ -4943,4 +4943,317 @@ function Get-HVTaskSpec { return $spec } -Export-ModuleMember Add-HVDesktop,Add-HVRDSServer,Connect-HVEvent,Disconnect-HVEvent,Get-HVEvent,Get-HVFarm,Get-HVFarmSummary,Get-HVPool,Get-HVPoolSummary,Get-HVQueryResult,Get-HVQueryFilter,New-HVFarm,New-HVPool,Remove-HVFarm,Remove-HVPool,Set-HVFarm,Set-HVPool,Start-HVFarm,Start-HVPool +function Find-HVMachine { + [CmdletBinding()] + param( + [Parameter(Mandatory = $true)] + $Param + ) + + $params = $Param + + try { + if ($params['PoolName']) { + $poolObj = Get-HVPoolSummary -poolName $params['PoolName'] -hvServer $params['HvServer'] + if ($poolObj.Length -ne 1) { + Write-Error "Failed to retrieve specific pool object with given PoolName : $params['PoolName']" + break; + } else { + $desktopId = $poolObj.Id + } + } + } catch { + Write-Error "Make sure Get-HVPoolSummary advanced function is loaded, $_" + break + } + # + # This translates the function arguments into the View API properties that must be queried + $machineSelectors = @{ + 'PoolName' = 'base.desktop'; + 'MachineName' = 'base.name'; + 'DnsName' = 'base.dnsName'; + 'State' = 'base.basicState'; + } + + + $query_service_helper = New-Object VMware.Hv.QueryServiceService + $query = New-Object VMware.Hv.QueryDefinition + + $wildCard = $false + #Only supports wild card '*' + if ($params['MachineName'] -and $params['MachineName'].contains('*')) { + $wildcard = $true + } + if ($params['DnsName'] -and $params['DnsName'].contains('*')) { + $wildcard = $true + } + # build the query values, MachineNamesView is having more info than + # MachineSummaryView + $query.queryEntityType = 'MachineNamesView' + if (! $wildcard) { + [VMware.Hv.queryfilter[]]$filterSet = @() + foreach ($setting in $machineSelectors.Keys) { + if ($null -ne $params[$setting]) { + $equalsFilter = New-Object VMware.Hv.QueryFilterEquals + $equalsFilter.memberName = $machineSelectors[$setting] + if ($equalsFilter.memberName -eq 'base.desktop') { + $equalsFilter.value = $desktopId + } else { + $equalsFilter.value = $params[$setting] + } + $filterSet += $equalsFilter + } + } + if ($filterSet.Count -gt 0) { + $andFilter = New-Object VMware.Hv.QueryFilterAnd + $andFilter.Filters = $filterset + $query.Filter = $andFilter + } + $queryResults = $query_service_helper.QueryService_Query($services,$query) + $machineList = $queryResults.results + } + if ($wildcard -or [string]::IsNullOrEmpty($machineList)) { + $query.Filter = $null + $queryResults = $query_service_helper.QueryService_Query($services,$query) + $strFilterSet = @() + foreach ($setting in $machineSelectors.Keys) { + if ($null -ne $params[$setting]) { + if ($wildcard -and (($setting -eq 'MachineName') -or ($setting -eq 'DnsName')) ) { + $strFilterSet += '($_.' + $machineSelectors[$setting] + ' -like "' + $params[$setting] + '")' + } else { + $strFilterSet += '($_.' + $machineSelectors[$setting] + ' -eq "' + $params[$setting] + '")' + } + } + } + $whereClause = [string]::Join(' -and ', $strFilterSet) + $scriptBlock = [Scriptblock]::Create($whereClause) + $machineList = $queryResults.results | where $scriptBlock + } + return $machineList +} + + +function Get-HVMachine { +<# +.Synopsis + Gets virtual Machine(s) information with given search parameters. + +.DESCRIPTION + Queries and returns virtual machines information, the machines list would be determined + based on queryable fields poolName, dnsName, machineName, state. When more than one + fields are used for query the virtual machines which satisfy all fields criteria would be returned. + +.PARAMETER PoolName + Pool name to query for. + If the value is null or not provided then filter will not be applied, + otherwise the virtual machines which has name same as value will be returned. + +.PARAMETER MachineName + The name of the Machine to query for. + If the value is null or not provided then filter will not be applied, + otherwise the virtual machines which has display name same as value will be returned. + +.PARAMETER DnsName + DNS name for the Machine to filter with. + If the value is null or not provided then filter will not be applied, + otherwise the virtual machines which has display name same as value will be returned. + +.PARAMETER State + The basic state of the Machine to filter with. + If the value is null or not provided then filter will not be applied, + otherwise the virtual machines which has display name same as value will be returned. + +.PARAMETER HvServer + Reference to Horizon View Server to query the virtual machines from. If the value is not passed or null then + first element from global:DefaultHVServers would be considered inplace of hvServer + +.EXAMPLE + Get-HVDesktop -PoolName 'ManualPool' + +.EXAMPLE + Get-HVDesktop -MachineName 'PowerCLIVM' + +.EXAMPLE + Get-HVDesktop -State CUSTOMIZING + +.EXAMPLE + Get-HVDesktop -DnsName 'powercli-*' -State CUSTOMIZING + +.OUTPUTS + Returns list of objects of type MachineInfo + +.NOTES + Author : Praveen Mathamsetty. + Author email : pmathamsetty@vmware.com + Version : 1.1 + + ===Tested Against Environment==== + Horizon View Server Version : 7.0.2, 7.0.3 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 5.0 +#> + + [CmdletBinding( + SupportsShouldProcess = $true, + ConfirmImpact = 'High' + )] + + param( + [Parameter(Mandatory = $false)] + [string] + $PoolName, + + [Parameter(Mandatory = $false)] + [string] + $MachineName, + + [Parameter(Mandatory = $false)] + [string] + $DnsName, + + [Parameter(Mandatory = $false)] + [ValidateSet('PROVISIONING','PROVISIONING_ERROR','WAIT_FOR_AGENT','CUSTOMIZING', + 'DELETING','MAINTENANCE','ERROR','PROVISIONED','AGENT_UNREACHABLE','UNASSIGNED_USER_CONNECTED', + 'CONNECTED','UNASSIGNED_USER_DISCONNECTED','DISCONNECTED','AGENT_ERR_STARTUP_IN_PROGRESS', + 'AGENT_ERR_DISABLED','AGENT_ERR_INVALID_IP','AGENT_ERR_NEED_REBOOT','AGENT_ERR_PROTOCOL_FAILURE', + 'AGENT_ERR_DOMAIN_FAILURE','AGENT_CONFIG_ERROR','ALREADY_USED','AVAILABLE','IN_PROGRESS','DISABLED', + 'DISABLE_IN_PROGRESS','VALIDATING','UNKNOWN')] + [string] + $State, + + [Parameter(Mandatory = $false)] + [string] + $JsonFilePath, + + [Parameter(Mandatory = $false)] + $HvServer = $null + ) + + $services = Get-ViewAPIService -hvServer $hvServer + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + + $machineList = Find-HVMachine -Param $PSBoundParameters + + if ($full) { + $queryResults = @() + $desktop_helper = New-Object VMware.Hv.MachineService + foreach ($id in $machineList.id) { + $info = $desktop_helper.Machine_Get($services,$id) + $queryResults += $info + } + $machineList = $queryResults + } + return $machineList +} + +function Get-HVMachineSummary { +<# +.Synopsis + Gets virtual Machine(s) summary with given search parameters. + +.DESCRIPTION + Queries and returns virtual machines information, the machines list would be determined + based on queryable fields poolName, dnsName, machineName, state. When more than one + fields are used for query the virtual machines which satisfy all fields criteria would be returned. + +.PARAMETER PoolName + Pool name to query for. + If the value is null or not provided then filter will not be applied, + otherwise the virtual machines which has name same as value will be returned. + +.PARAMETER MachineName + The name of the Machine to query for. + If the value is null or not provided then filter will not be applied, + otherwise the virtual machines which has display name same as value will be returned. + +.PARAMETER DnsName + DNS name for the Machine to filter with. + If the value is null or not provided then filter will not be applied, + otherwise the virtual machines which has display name same as value will be returned. + +.PARAMETER State + The basic state of the Machine to filter with. + If the value is null or not provided then filter will not be applied, + otherwise the virtual machines which has display name same as value will be returned. + +.PARAMETER HvServer + Reference to Horizon View Server to query the virtual machines from. If the value is not passed or null then + first element from global:DefaultHVServers would be considered inplace of hvServer + +.EXAMPLE + Get-HVDesktopSummary -PoolName 'ManualPool' + +.EXAMPLE + Get-HVDesktopSummary -MachineName 'PowerCLIVM' + +.EXAMPLE + Get-HVDesktopSummary -State CUSTOMIZING + +.EXAMPLE + Get-HVDesktopSummary -DnsName 'powercli-*' -State CUSTOMIZING + +.OUTPUTS + Returns list of objects of type MachineNamesView + +.NOTES + Author : Praveen Mathamsetty. + Author email : pmathamsetty@vmware.com + Version : 1.1 + + ===Tested Against Environment==== + Horizon View Server Version : 7.0.2, 7.0.3 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 5.0 +#> + + [CmdletBinding( + SupportsShouldProcess = $true, + ConfirmImpact = 'High' + )] + + param( + [Parameter(Mandatory = $false)] + [string] + $PoolName, + + [Parameter(Mandatory = $false)] + [string] + $MachineName, + + [Parameter(Mandatory = $false)] + [string] + $DnsName, + + [Parameter(Mandatory = $false)] + [ValidateSet('PROVISIONING','PROVISIONING_ERROR','WAIT_FOR_AGENT','CUSTOMIZING', + 'DELETING','MAINTENANCE','ERROR','PROVISIONED','AGENT_UNREACHABLE','UNASSIGNED_USER_CONNECTED', + 'CONNECTED','UNASSIGNED_USER_DISCONNECTED','DISCONNECTED','AGENT_ERR_STARTUP_IN_PROGRESS', + 'AGENT_ERR_DISABLED','AGENT_ERR_INVALID_IP','AGENT_ERR_NEED_REBOOT','AGENT_ERR_PROTOCOL_FAILURE', + 'AGENT_ERR_DOMAIN_FAILURE','AGENT_CONFIG_ERROR','ALREADY_USED','AVAILABLE','IN_PROGRESS','DISABLED', + 'DISABLE_IN_PROGRESS','VALIDATING','UNKNOWN')] + [string] + $State, + + [Parameter(Mandatory = $false)] + [string] + $JsonFilePath, + + [Parameter(Mandatory = $false)] + $HvServer = $null + ) + + $services = Get-ViewAPIService -hvServer $hvServer + if ($null -eq $services) { + Write-Error "Could not retrieve ViewApi services from connection object" + break + } + + $machineList = Find-HVMachine -Param $PSBoundParameters + return $machineList +} + + + From 7a5ae91379309c643985129c1132b8e86367876a Mon Sep 17 00:00:00 2001 From: baoyinqiao Date: Wed, 14 Dec 2016 08:57:43 +0800 Subject: [PATCH 04/11] Add a new VIProperty: KMSserver for VM As Mike suggested, add a new VI Property to retrieve the KMSserver ClusterId for encrypted VMs. --- Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 index 149fd49..f14973a 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 @@ -59,6 +59,13 @@ New-VIProperty -Name Locked -ObjectType VirtualMachine -Value { ($vm.extensiondata.Runtime.ConnectionState -eq "invalid") -and ($vm.extensiondata.Config.KeyId) } -BasedOnExtensionProperty 'Runtime.ConnectionState','Config.KeyId' -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 From 9f8d094e387566a4d90f37bad4b37276a57f3718 Mon Sep 17 00:00:00 2001 From: baoyinqiao Date: Wed, 14 Dec 2016 09:02:47 +0800 Subject: [PATCH 05/11] Fix the indentation of Encrypted Property of disk Identation fix. --- Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 index f14973a..8594bf9 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 @@ -67,8 +67,8 @@ New-VIProperty -Name KMSserver -ObjectType VirtualMachine -Value { } -BasedOnExtensionProperty 'Config.KeyId' -Force | Out-Null New-VIProperty -Name Encrypted -ObjectType HardDisk -Value { - Param ($hardDisk) - $hardDisk.ExtensionData.Backing.KeyId -ne $null + Param ($hardDisk) + $hardDisk.ExtensionData.Backing.KeyId -ne $null } -BasedOnExtensionProperty 'Backing.KeyId' -Force | Out-Null New-VIProperty -Name EncryptionKeyId -ObjectType HardDisk -Value { From 8b0750a94ee3a2d3f6de1b6ef22d50b7d4651076 Mon Sep 17 00:00:00 2001 From: praveenmathamsetty Date: Fri, 16 Dec 2016 10:04:04 +0530 Subject: [PATCH 06/11] Write-Error to Write-Host In Find-HVMachine using Write-Host instead of Write-Error --- Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index 2a8b70a..17bba20 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -1,7 +1,7 @@ #Script Module : VMware.Hv.Helper #Version : 1.0 -#Copyright © 2016 VMware, Inc. All Rights Reserved. +#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 @@ -1844,7 +1844,7 @@ function New-HVFarm { Reference to Horizon View Server to query the farms from. If the value is not passed or null then first element from global:DefaultHVServers would be considered inplace of hvServer. .EXAMPLE - New-HVFarm -LinkedClone -FarmName 'LCFarmTest' -ParentVM 'Win_Server_2012_R2' -SnapshotVM 'Snap_RDS' -VmFolder 'PoolVM' -HostOrCluster 'cls' -ResourcePool 'cls' -Datastores 'datastore1 (5)' -FarmDisplayName 'LC Farm Test' -Description  'created LC Farm from PS' -EnableProvisioning $true -StopOnProvisioningError $false -NamingPattern  "LCFarmVM_PS" -MinReady 1 -MaximumCount 1 -SysPrepName "RDSH_Cust2" -NetBiosName "adviewdev" + New-HVFarm -LinkedClone -FarmName 'LCFarmTest' -ParentVM 'Win_Server_2012_R2' -SnapshotVM 'Snap_RDS' -VmFolder 'PoolVM' -HostOrCluster 'cls' -ResourcePool 'cls' -Datastores 'datastore1 (5)' -FarmDisplayName 'LC Farm Test' -Description  'created LC Farm from PS' -EnableProvisioning $true -StopOnProvisioningError $false -NamingPattern  "LCFarmVM_PS" -MinReady 1 -MaximumCount 1 -SysPrepName "RDSH_Cust2" -NetBiosName "adviewdev" .EXAMPLE New-HVFarm -Spec C:\VMWare\Specs\LinkedClone.json @@ -4956,7 +4956,7 @@ function Find-HVMachine { if ($params['PoolName']) { $poolObj = Get-HVPoolSummary -poolName $params['PoolName'] -hvServer $params['HvServer'] if ($poolObj.Length -ne 1) { - Write-Error "Failed to retrieve specific pool object with given PoolName : $params['PoolName']" + Write-Host "Failed to retrieve specific pool object with given PoolName : "$params['PoolName'] break; } else { $desktopId = $poolObj.Id From df17793edeedc64f80456592b4f4873e82450647 Mon Sep 17 00:00:00 2001 From: praveenmathamsetty Date: Mon, 19 Dec 2016 13:07:44 +0530 Subject: [PATCH 07/11] Fix for formatting Get-HVMachineSummary and empty search results. Displays proper meesage for Get-HVMachine/Get-HVMAchineSummary, incase of empty search results. Dispalying Agent sataus for Get-HVMachineSummary result. --- .../VMware.HV.Helper.format.ps1xml | 31 ++++++++++--------- .../VMware.Hv.Helper/VMware.HV.Helper.psm1 | 25 +++++++++------ 2 files changed, 32 insertions(+), 24 deletions(-) diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.format.ps1xml b/Modules/VMware.Hv.Helper/VMware.HV.Helper.format.ps1xml index dc4cca4..62ce001 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.format.ps1xml +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.format.ps1xml @@ -29,7 +29,7 @@ - 8 + 7 @@ -117,27 +117,27 @@ - 16 + 15 - 16 + 12 - 16 + 12 - 16 + 8 - 16 + 15 - 8 + 5 @@ -145,9 +145,8 @@ - 10 + 15 - Right @@ -169,13 +168,13 @@ $_.ManagedMachineNamesData.HostName - $_.Data.AgentVersion + $_.Base.AgentVersion $_.ManagedMachineNamesData.DatastorePaths - $_.Data.BasicState + $_.Base.BasicState @@ -212,12 +211,16 @@ $_.ManagedMachineNamesData.HostName - + + $_.Base.AgentVersion + + + $_.ManagedMachineNamesData.DatastorePaths - - $_.Data.BasicState + + $_.Base.BasicState diff --git a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 index 17bba20..583933d 100644 --- a/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 +++ b/Modules/VMware.Hv.Helper/VMware.HV.Helper.psm1 @@ -5136,16 +5136,17 @@ function Get-HVMachine { } $machineList = Find-HVMachine -Param $PSBoundParameters - - if ($full) { - $queryResults = @() - $desktop_helper = New-Object VMware.Hv.MachineService - foreach ($id in $machineList.id) { - $info = $desktop_helper.Machine_Get($services,$id) - $queryResults += $info - } - $machineList = $queryResults + if (!$machineList) { + Write-Host "No Virtual Machine(s) Found with given search parameters" + break } + $queryResults = @() + $desktop_helper = New-Object VMware.Hv.MachineService + foreach ($id in $machineList.id) { + $info = $desktop_helper.Machine_Get($services,$id) + $queryResults += $info + } + $machineList = $queryResults return $machineList } @@ -5252,8 +5253,12 @@ function Get-HVMachineSummary { } $machineList = Find-HVMachine -Param $PSBoundParameters + if (!$machineList) { + Write-Host "No Virtual Machine(s) Found with given search parameters" + break + } return $machineList } - +Export-ModuleMember Add-HVDesktop,Add-HVRDSServer,Connect-HVEvent,Disconnect-HVEvent,Get-HVEvent,Get-HVFarm,Get-HVFarmSummary,Get-HVPool,Get-HVPoolSummary,Get-HVMachine,Get-HVMachineSummary,Get-HVQueryResult,Get-HVQueryFilter,New-HVFarm,New-HVPool,Remove-HVFarm,Remove-HVPool,Set-HVFarm,Set-HVPool,Start-HVFarm,Start-HVPool From ce69869e8a6518c26214be82e27aaf9c76728d8a Mon Sep 17 00:00:00 2001 From: yangm Date: Mon, 19 Dec 2016 00:29:52 -0800 Subject: [PATCH 08/11] add 1 property to VM, 1 function --- .../VMware.VMEncryption.psm1 | 88 +++++++++++++++---- 1 file changed, 70 insertions(+), 18 deletions(-) diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 index 8594bf9..5f23ca0 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 @@ -59,6 +59,11 @@ New-VIProperty -Name Locked -ObjectType VirtualMachine -Value { ($vm.extensiondata.Runtime.ConnectionState -eq "invalid") -and ($vm.extensiondata.Config.KeyId) } -BasedOnExtensionProperty '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) { @@ -108,7 +113,6 @@ Function Enable-VMHostCryptoSafe { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -177,7 +181,6 @@ Function Set-VMHostCryptoKey { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -231,6 +234,71 @@ Function Set-VMHostCryptoKey { } } +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 : Carrie Yang + Author email : yangm@vmware.com + Version : 1.0 + + ==========Tested Against Environment========== + VMware vSphere Hypervisor(ESXi) Version : 6.5 + VMware vCenter Server Version : 6.5 + PowerCLI Version : PowerCLI 6.5 + PowerShell Version : 3.0 + #> + + [CmdLetBinding()] + + param ( + [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] + [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM, + + [ValidateSet("disabled", "opportunistic", "required")] + [String]$Encryption + ) + + process{ + # Confirm the connected VIServer is vCenter Server + ConfirmIsVCenter + + if ($VM.Encrypted -and $VM.vMotionEncryption -ne $Encryption) { + 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 @@ -277,7 +345,6 @@ Function Enable-VMEncryption { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -438,7 +505,6 @@ Function Enable-VMDiskEncryption { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -591,7 +657,6 @@ Function Disable-VMEncryption { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -688,7 +753,6 @@ Function Disable-VMDiskEncryption { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -824,7 +888,6 @@ Function Set-VMEncryptionKey { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -981,7 +1044,6 @@ Function Set-VMDiskEncryptionKey { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -1105,7 +1167,6 @@ Function Get-VMEncryptionInfo { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -1205,7 +1266,6 @@ Function Get-EntityByCryptoKey { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -1331,7 +1391,6 @@ Function New-KMServer { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -1491,7 +1550,6 @@ Function Remove-KMServer { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -1569,7 +1627,6 @@ Function Get-KMSCluster { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> # Confirm the connected VIServer is vCenter Server @@ -1661,7 +1718,6 @@ Function Get-KMServerInfo { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -1723,7 +1779,6 @@ Function Get-KMServerStatus { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -1795,7 +1850,6 @@ Function Get-DefaultKMSCluster { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> # Confirm the connected VIServer is vCenter Server @@ -1833,7 +1887,6 @@ Function Set-DefaultKMSCluster { VMware vCenter Server Version : 6.5 PowerCLI Version : PowerCLI 6.5 PowerShell Version : 3.0 - #> [CmdLetBinding()] @@ -1889,7 +1942,6 @@ Function ConfirmHardDiskIsValid { .PARAMETER HardDisk Specifies the hard disks which you want to use to validate. - #> [CmdLetBinding()] From 7d49541a258f79ba0e54162e734ccc33c14101e5 Mon Sep 17 00:00:00 2001 From: yangm Date: Tue, 20 Dec 2016 19:41:59 -0800 Subject: [PATCH 09/11] add 1 property and 1 function for vMotionEncryption --- .../VMware.VMEncryption.psm1 | 45 ++++++++++--------- 1 file changed, 24 insertions(+), 21 deletions(-) diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 index 5f23ca0..5252f96 100644 --- a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 +++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 @@ -69,7 +69,7 @@ New-VIProperty -Name KMSserver -ObjectType VirtualMachine -Value { if ($VM.Encrypted) { $VM.EncryptionKeyId.ProviderId.Id } - } -BasedOnExtensionProperty 'Config.KeyId' -Force | Out-Null +} -BasedOnExtensionProperty 'Config.KeyId' -Force | Out-Null New-VIProperty -Name Encrypted -ObjectType HardDisk -Value { Param ($hardDisk) @@ -238,7 +238,7 @@ 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 @@ -248,17 +248,17 @@ Function Set-vMotionEncryptionConfig { 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. + 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 : Carrie Yang - Author email : yangm@vmware.com + Author : Brian Graf, Carrie Yang. + Author email : grafb@vmware.com, yangm@vmware.com Version : 1.0 ==========Tested Against Environment========== @@ -274,28 +274,31 @@ Function Set-vMotionEncryptionConfig { [Parameter(Mandatory=$True,ValueFromPipeline=$True,ValueFromPipelinebyPropertyName=$True)] [VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine]$VM, + [Parameter(Mandatory=$True] [ValidateSet("disabled", "opportunistic", "required")] - [String]$Encryption + [String]$Encryption ) process{ - # Confirm the connected VIServer is vCenter Server - ConfirmIsVCenter + if ($VM.vMotionEncryption -eq $Encryption) { + Write-Warning "The encrypted vMotion state is already $Encrypted, no need to change it." + return + } - if ($VM.Encrypted -and $VM.vMotionEncryption -ne $Encryption) { + 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" - + $Config = New-Object VMware.Vim.VirtualMachineConfigSpec + $Config.MigrateEncryption = New-Object VMware.Vim.VirtualMachineConfigSpecEncryptedVMotionModes + $Config.MigrateEncryption = $Encryption + $VMView.ReconfigVM($config) - $VM.ExtensionData.UpdateViewData() - $VM.vMotionEncryption + $VM.ExtensionData.UpdateViewData() + $VM.vMotionEncryption } } @@ -1156,7 +1159,7 @@ Function Get-VMEncryptionInfo { .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 @@ -1255,7 +1258,7 @@ Function Get-EntityByCryptoKey { .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 @@ -1876,7 +1879,7 @@ Function Set-DefaultKMSCluster { 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 From 58ba21aacdae679b30b7ed9e088d51dc617f171c Mon Sep 17 00:00:00 2001 From: mycloudrevolution Date: Thu, 22 Dec 2016 23:19:54 +0100 Subject: [PATCH 10/11] sets the Basic settings for a new ESXi This Function sets the Basic settings for a new ESXi. * NTP * SSH * Syslog * Power Management * HP 3PAR SATP/PSP Rule * ... --- Modules/Konfig-ESXi.psm1 | 234 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 234 insertions(+) create mode 100644 Modules/Konfig-ESXi.psm1 diff --git a/Modules/Konfig-ESXi.psm1 b/Modules/Konfig-ESXi.psm1 new file mode 100644 index 0000000..f14386a --- /dev/null +++ b/Modules/Konfig-ESXi.psm1 @@ -0,0 +1,234 @@ +function Konfig-ESXi { +<# + .NOTES + =========================================================================== + Created by: Markus Kraus + Twitter: @VMarkus_K + Private Blog: mycloudrevolution.com + =========================================================================== + Changelog: + 2016.12 ver 1.0 Base Release + 2016.12 ver 1.1 ESXi 6.5 Tests, Minor enhancements + =========================================================================== + External Code Sources: + Function My-Logger : http://www.virtuallyghetto.com/ + =========================================================================== + Tested Against Environment: + vSphere Version: ESXi 5.5 U2, ESXi 6.5 + PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1 + PowerShell Version: 4.0, 5.0 + OS Version: Windows 8.1, Server 2012 R2 + Keyword: ESXi, NTP, SSH, Syslog, SATP, + =========================================================================== + + .DESCRIPTION + This Function sets the Basic settings for a new ESXi. + + * NTP + * SSH + * Syslog + * Power Management + * HP 3PAR SATP/PSP Rule + * ... + + .Example + Konfig-ESXi -VMHost myesxi.lan.local -NTP 192.168.2.1, 192.168.2.2 -syslog "udp://loginsight.lan.local:514" + + .PARAMETER VMHost + Host to configure. + + .PARAMETER NTP + NTP Server(s) to set. + + .PARAMETER Syslog + Syslog Server to set, e.g. "udp://loginsight.lan.local:514" + + DNS Name must be resolvable! + + +#Requires PS -Version 4.0 +#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"} +#> + +[CmdletBinding()] +param( + [Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)] + [String] $VMHost, + [Parameter(Mandatory=$true, ValueFromPipeline=$False, Position=1)] + [array]$NTP, + [Parameter(Mandatory=$true, ValueFromPipeline=$False, Position=2)] + [String] $syslog + +) + +Begin { + Function My-Logger { + param( + [Parameter(Mandatory=$true)] + [String]$message + ) + + $timeStamp = Get-Date -Format "MM-dd-yyyy_hh-mm-ss" + + Write-Host -NoNewline -ForegroundColor White "[$timestamp]" + Write-Host -ForegroundColor Green " $message" + } + function Set-MyESXiOption { + [CmdletBinding()] + param( + [Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)] + [String] $Name, + [Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=1)] + [String] $Value + ) + process { + $myESXiOption = Get-AdvancedSetting -Entity $ESXiHost -Name $Name + if ($myESXiOption.Value -ne $Value) { + My-Logger " Setting ESXi Option $Name to Value $Value" + $myESXiOption | Set-AdvancedSetting -Value $Value -Confirm:$false | Out-Null + } + else { + My-Logger " ESXi Option $Name already has Value $Value" + } + } + } +} + +Process { + $Validate = $True + + #region: Start vCenter Connection + My-Logger "Starting to Process ESXi Server Connection to $VMHost ..." + if (($global:DefaultVIServers).count -gt 0) { + Disconnect-VIServer -Force -Confirm:$False -ErrorAction SilentlyContinue + } + $VIConnection = Connect-VIServer -Server $VMHost + if (-not $VIConnection.IsConnected) { + Write-Error "ESXi Connection Failed." + $Validate = $False + } + elseif ($VIConnection.ProductLine -ne "EmbeddedEsx") { + Write-Error "Connencted System is not an ESXi." + $Validate = $False + } + else { + $ESXiHost = Get-VMHost + My-Logger "Connected ESXi Version: $($ESXiHost.Version) $($ESXiHost.Build) " + } + #endregion + + if ($Validate -eq $True) { + + #region: Enable SSH and disable SSH Warning + $SSHService = $ESXiHost | Get-VMHostService | where {$_.Key -eq 'TSM-SSH'} + My-Logger "Starting SSH Service..." + if($SSHService.Running -ne $True){ + Start-VMHostService -HostService $SSHService -Confirm:$false | Out-Null + } + else { + My-Logger " SSH Service is already running" + } + My-Logger "Setting SSH Service to Automatic Start..." + if($SSHService.Policy -ne "automatic"){ + Set-VMHostService -HostService $SSHService -Policy "Automatic" | Out-Null + } + else { + My-Logger " SSH Service is already set to Automatic Start" + } + My-Logger "Disabling SSH Warning..." + Set-MyESXiOption -Name "UserVars.SuppressShellWarning" -Value "1" + #endregion + + #region: Config NTP + My-Logger "Removing existing NTP Server..." + try { + $ESXiHost | Remove-VMHostNtpServer -NtpServer (Get-VMHostNtpServer) -Confirm:$false + } + catch [System.Exception] { + Write-Warning "Error during removing existing NTP Servers." + } + My-Logger "Setting new NTP Servers..." + foreach ($myNTP in $NTP) { + $ESXiHost | Add-VMHostNtpServer -ntpserver $myNTP -confirm:$False | Out-Null + } + + My-Logger "Configure NTP Service..." + $NTPService = $ESXiHost | Get-VMHostService| Where-Object {$_.key -eq "ntpd"} + if($NTPService.Running -eq $True){ + Stop-VMHostService -HostService $NTPService -Confirm:$false | Out-Null + } + if($NTPService.Policy -ne "on"){ + Set-VMHostService -HostService $NTPService -Policy "on" -confirm:$False | Out-Null + } + + My-Logger "Configure Local Time..." + $HostTimeSystem = Get-View $ESXiHost.ExtensionData.ConfigManager.DateTimeSystem + $HostTimeSystem.UpdateDateTime([DateTime]::UtcNow) + + My-Logger "Start NTP Service..." + Start-VMHostService -HostService $NTPService -confirm:$False | Out-Null + #endregion + + #region: Remove default PG + My-Logger "Checking for Default Port Group ..." + if ($defaultPG = $ESXiHost | Get-VirtualSwitch -Name vSwitch0 | Get-VirtualPortGroup -Name "VM Network" -ErrorAction SilentlyContinue ){ + Remove-VirtualPortGroup -VirtualPortGroup $defaultPG -confirm:$False | Out-Null + My-Logger " Default PG Removed" + } + else { + My-Logger " No Default PG found" + } + #endregion + + #region: Configure Static HighPower + My-Logger "Setting PowerProfile to Static HighPower..." + try { + $HostView = ($ESXiHost | Get-View) + (Get-View $HostView.ConfigManager.PowerSystem).ConfigurePowerPolicy(1) + } + catch [System.Exception] { + Write-Warning "Error during Configure Static HighPower. See latest errors..." + } + #endregion + + #region: Conf Syslog + My-Logger "Setting Syslog Firewall Rule ..." + $SyslogFW = ($ESXiHost | Get-VMHostFirewallException | where {$_.Name -eq 'syslog'}) + if ($SyslogFW.Enabled -eq $False ){ + $SyslogFW | Set-VMHostFirewallException -Enabled:$true -Confirm:$false | Out-Null + My-Logger " Syslog Firewall Rule enabled" + } + else { + My-Logger " Syslog Firewall Rule already enabled" + } + My-Logger "Setting Syslog Server..." + Set-MyESXiOption -Name "Syslog.global.logHost" -Value $syslog + #endregion + + #region: Change Disk Scheduler + My-Logger "Changing Disk Scheduler..." + Set-MyESXiOption -Name "Disk.SchedulerWithReservation" -Value "0" + #endregion + + #region: Configure HP 3PAR SATP/PSP Rule + My-Logger "Configure HP 3PAR SATP/PSP Rule" + $esxcli2 = Get-ESXCLI -VMHost $ESXiHost -V2 + $arguments = $esxcli2.storage.nmp.satp.rule.add.CreateArgs() + $arguments.satp = "VMW_SATP_ALUA" + $arguments.psp = "VMW_PSP_RR" + $arguments.pspoption = "iops=100" + $arguments.claimoption = "tpgs_on" + $arguments.vendor = "3PARdata" + $arguments.model = "VV" + $arguments.description = "HP 3PAR custom SATP Claimrule" + try { + $esxcli2.storage.nmp.satp.rule.add.Invoke($arguments) + } + catch { + Write-Warning "Error during Configure HP 3PAR SATP/PSP Rule. See latest errors..." + } + #endregion + + } + } +} From 559db31acaba80ab59bfef9cb33751b435df750f Mon Sep 17 00:00:00 2001 From: mycloudrevolution Date: Fri, 23 Dec 2016 14:30:57 +0100 Subject: [PATCH 11/11] added Get-NewAndRemovedVMs Function This Function report newly created and deleted VMs by Cluster. --- Modules/Get-NewAndRemovedVMs.psm1 | 131 ++++++++++++++++++++++++++++++ 1 file changed, 131 insertions(+) create mode 100644 Modules/Get-NewAndRemovedVMs.psm1 diff --git a/Modules/Get-NewAndRemovedVMs.psm1 b/Modules/Get-NewAndRemovedVMs.psm1 new file mode 100644 index 0000000..4a2e3ba --- /dev/null +++ b/Modules/Get-NewAndRemovedVMs.psm1 @@ -0,0 +1,131 @@ +function Get-NewAndRemovedVMs { +<# + .NOTES + =========================================================================== + Created by: Markus Kraus + Twitter: @VMarkus_K + Private Blog: mycloudrevolution.com + =========================================================================== + Changelog: + 2016.12 ver 1.0 Base Release + =========================================================================== + External Code Sources: + https://github.com/alanrenouf/vCheck-vSphere + =========================================================================== + Tested Against Environment: + vSphere Version: 5.5 U2 + PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1 + PowerShell Version: 4.0, 5.0 + OS Version: Windows 8.1, Server 2012 R2 + =========================================================================== + Keywords vSphere, VM + =========================================================================== + + .DESCRIPTION + This Function report newly created and deleted VMs by Cluster. + + .Example + Get-NewAndRemovedVMs -ClusterName Cluster* | ft -AutoSize + + .Example + Get-NewAndRemovedVMs -ClusterName Cluster01 -Days 90 + + .PARAMETER ClusterName + Name or Wildcard of your vSphere Cluster Name(s) to report. + + .PARAMETER Day + Range in Days to report. + + +#Requires PS -Version 4.0 +#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"} +#> + +param( + [Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0, HelpMessage = "Name or Wildcard of your vSphere Cluster Name to report")] + [ValidateNotNullorEmpty()] + [String]$ClusterName, + [Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=1, HelpMessage = "Range in Days to report")] + [ValidateNotNullorEmpty()] + [String]$Days = "30" +) +Begin { + function Get-VIEventPlus { + + param( + [VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]$Entity, + [string[]]$EventType, + [DateTime]$Start, + [DateTime]$Finish = (Get-Date), + [switch]$Recurse, + [string[]]$User, + [Switch]$System, + [string]$ScheduledTask, + [switch]$FullMessage = $false, + [switch]$UseUTC = $false + ) + + process { + $eventnumber = 100 + $events = @() + $eventMgr = Get-View EventManager + $eventFilter = New-Object VMware.Vim.EventFilterSpec + $eventFilter.disableFullMessage = ! $FullMessage + $eventFilter.entity = New-Object VMware.Vim.EventFilterSpecByEntity + $eventFilter.entity.recursion = &{if($Recurse){"all"}else{"self"}} + $eventFilter.eventTypeId = $EventType + if($Start -or $Finish){ + $eventFilter.time = New-Object VMware.Vim.EventFilterSpecByTime + if($Start){ + $eventFilter.time.beginTime = $Start + } + if($Finish){ + $eventFilter.time.endTime = $Finish + } + } + if($User -or $System){ + $eventFilter.UserName = New-Object VMware.Vim.EventFilterSpecByUsername + if($User){ + $eventFilter.UserName.userList = $User + } + if($System){ + $eventFilter.UserName.systemUser = $System + } + } + if($ScheduledTask){ + $si = Get-View ServiceInstance + $schTskMgr = Get-View $si.Content.ScheduledTaskManager + $eventFilter.ScheduledTask = Get-View $schTskMgr.ScheduledTask | + where {$_.Info.Name -match $ScheduledTask} | + Select -First 1 | + Select -ExpandProperty MoRef + } + if(!$Entity){ + $Entity = @(Get-Folder -NoRecursion) + } + $entity | %{ + $eventFilter.entity.entity = $_.ExtensionData.MoRef + $eventCollector = Get-View ($eventMgr.CreateCollectorForEvents($eventFilter)) + $eventsBuffer = $eventCollector.ReadNextEvents($eventnumber) + while($eventsBuffer){ + $events += $eventsBuffer + $eventsBuffer = $eventCollector.ReadNextEvents($eventnumber) + } + $eventCollector.DestroyCollector() + } + if (-not $UseUTC) + { + $events | % { $_.createdTime = $_.createdTime.ToLocalTime() } + } + + $events + } +} +} + +process { + $result = Get-VIEventPlus -Start ((get-date).adddays(-$Days)) -EventType @("VmCreatedEvent", "VmBeingClonedEvent", "VmBeingDeployedEvent","VmRemovedEvent") + $sortedResult = $result | Select CreatedTime, @{N='Cluster';E={$_.ComputeResource.Name}}, @{Name="VMName";Expression={$_.vm.name}}, UserName, @{N='Type';E={$_.GetType().Name}}, FullFormattedMessage | Sort CreatedTime + $sortedResult | where {$_.Cluster -like $ClusterName} +} +} \ No newline at end of file