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
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
+
+ }
+ }
+}
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 6884703..583933d 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
@@ -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] + '")'
}
}
}
@@ -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
@@ -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,322 @@ 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-Host "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 (!$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
+}
+
+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
+ 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
+
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 0000000..d310632
Binary files /dev/null and b/Modules/VMware.VMEncryption/VMware.VMEncryption.psd1 differ
diff --git a/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1 b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1
new file mode 100644
index 0000000..5252f96
--- /dev/null
+++ b/Modules/VMware.VMEncryption/VMware.VMEncryption.psm1
@@ -0,0 +1,2107 @@
+# 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 vMotionEncryption -ObjectType VirtualMachine -Value {
+ Param ($VM)
+ $VM.ExtensionData.Config.MigrateEncryption
+} -BasedOnExtensionProperty 'Config.MigrateEncryption' -Force | Out-Null
+
+New-VIProperty -Name KMSserver -ObjectType VirtualMachine -Value {
+ Param ($VM)
+ if ($VM.Encrypted) {
+ $VM.EncryptionKeyId.ProviderId.Id
+ }
+} -BasedOnExtensionProperty 'Config.KeyId' -Force | Out-Null
+
+New-VIProperty -Name Encrypted -ObjectType HardDisk -Value {
+ Param ($hardDisk)
+ $hardDisk.ExtensionData.Backing.KeyId -ne $null
+} -BasedOnExtensionProperty 'Backing.KeyId' -Force | Out-Null
+
+New-VIProperty -Name EncryptionKeyId -ObjectType HardDisk -Value {
+ Param ($Disk)
+ if ($Disk.Encrypted) {
+ $Disk.ExtensionData.Backing.KeyId
+ }
+} -BasedOnExtensionProperty 'Backing.KeyId' -Force | Out-Null
+
+Function Enable-VMHostCryptoSafe {
+ <#
+ .SYNOPSIS
+ This cmdlet enables the VMHost's CryptoSate to safe.
+
+ .DESCRIPTION
+ This cmdlet enables the VMHost's CryptoSate to safe.
+
+ .PARAMETER VMHost
+ Specifies the VMHost you want to enable.
+
+ .PARAMETER KMSClusterId
+ Specifies the KMS cluster ID which you want to use to generate the encrytion key.
+
+ .EXAMPLE
+ C:\PS>$VMHost = Get-VMHost -name $VMHostName
+ C:\PS>Enable-VMHostCryptoSafe -VMHost $VMHost
+
+ Enables the specified VMHost's CryptoSate to safe.
+
+ .NOTES
+ Author : Baoyin Qiao.
+ Author email : bqiao@vmware.com
+ 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 Set-vMotionEncryptionConfig {
+ <#
+ .SYNOPSIS
+ This cmdlet sets the vMotionEncryption property of a VM.
+
+ .DESCRIPTION
+ Use this function to set the vMotionEncryption settings for a VM.
+ The 'Encryption' parameter is set up with Tab-Complete for the available
+ options.
+
+ .PARAMETER VM
+ Specifies the VM you want to set the vMotionEncryption property.
+
+ .PARAMETER Encryption
+ Specifies the value you want to set to the vMotionEncryption property.
+ The Encryption options are: disabled, opportunistic, and required.
+
+ .EXAMPLE
+ PS C:\> Get-VM | Set-vMotionEncryptionConfig -Encryption opportunistic
+
+ Sets the vMotionEncryption of all the VMs
+
+ .NOTES
+ Author : Brian Graf, Carrie Yang.
+ Author email : grafb@vmware.com, yangm@vmware.com
+ 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]
+ [ValidateSet("disabled", "opportunistic", "required")]
+ [String]$Encryption
+ )
+
+ process{
+ if ($VM.vMotionEncryption -eq $Encryption) {
+ Write-Warning "The encrypted vMotion state is already $Encrypted, no need to change it."
+ return
+ }
+
+ if ($VM.Encrypted) {
+ Write-Error "Cannot change encrypted vMotion state for an encrypted VM."
+ return
+ }
+
+ $VMView = $VM | get-view
+ $Config = New-Object VMware.Vim.VirtualMachineConfigSpec
+ $Config.MigrateEncryption = New-Object VMware.Vim.VirtualMachineConfigSpecEncryptedVMotionModes
+ $Config.MigrateEncryption = $Encryption
+
+ $VMView.ReconfigVM($config)
+
+ $VM.ExtensionData.UpdateViewData()
+ $VM.vMotionEncryption
+ }
+}
+
+Function Enable-VMEncryption {
+ <#
+ .SYNOPSIS
+ This cmdlet encrypts the specified VM.
+
+ .DESCRIPTION
+ This cmdlet encrypts the specified VM.
+
+ .PARAMETER SkipHardDisks
+ If specified, skips the encryption of the hard disks of the specified VM.
+
+ .PARAMETER VM
+ Specifies the VM you want to encrypt.
+
+ .PARAMETER Policy
+ Specifies the encryption policy you want to use.
+
+ .PARAMETER KMSClusterId
+ Specifies the KMS clusterId you want to use to generate new key for encryption.
+
+ .EXAMPLE
+ C:\PS>Get-VM -Name win2012|Enable-VMEncryption
+
+ Encrypts the whole VM with default encryption policy.
+
+ .EXAMPLE
+ C:\PS>$SP = Get-SpbmStoragePolicy -name "EncryptionPol"
+ C:\PS>Get-VM -Name win2012 |Enable-VMEncryption -Policy $SP -SkipHardDisks
+
+ Encrypts the VM Home with the encryption policy 'EncryptionPol' and skips hard disks encryption.
+
+ .NOTES
+ This cmdlet assumes there already is KMS defined in vCenter Server.
+ If VM Home is already encrypted, the cmdlet quits.
+ If VM Home is not encrypted, encrypt VM Home if SkipHardDisks specified. Otherwise encrypt the VM Home and VM-attached disks.
+
+ .NOTES
+ Author : Baoyin Qiao.
+ Author email : bqiao@vmware.com
+ 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 *-*
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
+}