Merge remote-tracking branch 'refs/remotes/vmware/master'
This commit is contained in:
114
Modules/Get-VMmaxIOPS.psm1
Normal file
114
Modules/Get-VMmaxIOPS.psm1
Normal file
@@ -0,0 +1,114 @@
|
||||
function Get-VMmaxIOPS {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.10 ver 1.0 Base Release
|
||||
2016.11 ver 1.1 Added vSphere 6.5 Support, New Counters, More Error Handling
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
http://www.lucd.info/2011/04/22/get-the-maximum-iops/
|
||||
https://communities.vmware.com/thread/485386
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: 5.5 U2, 6.5
|
||||
PowerCLI Version: PowerCLI 6.3 R1, 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Windows Server 2012 R2
|
||||
===========================================================================
|
||||
Keywords vSphere, ESXi, VM, Storage
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function will Create a VM Disk IOPS Report
|
||||
|
||||
.Example
|
||||
Get-VM TST* | Get-VMmaxIOPS -Minutes 60 | FT -Autosize
|
||||
|
||||
.Example
|
||||
$SampleVMs = Get-VM "TST*"
|
||||
Get-VMmaxIOPS -VMs $SampleVMs -Minutes 60
|
||||
|
||||
.PARAMETER VMs
|
||||
Specify the VMs
|
||||
|
||||
.PARAMETER Minutes
|
||||
Specify the Minutes to report (10080 is one Week)
|
||||
|
||||
#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=$True, Position=0)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]] $VMs,
|
||||
[Parameter(Mandatory=$false, Position=1, HelpMessage = "Specify the Minutes to report (10080 is one Week)")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[int] $Minutes = 30
|
||||
)
|
||||
Begin {
|
||||
# none
|
||||
}
|
||||
Process {
|
||||
if ($_.PowerState -eq "PoweredOn") {
|
||||
#region: Global Definitions
|
||||
[int]$TimeRange = "-" + $Minutes
|
||||
#endregion
|
||||
|
||||
#region: Creating VM Stats
|
||||
Write-Verbose "$(Get-Date -Format G) Create VM Stats..."
|
||||
$VMMetrics = "virtualdisk.numberwriteaveraged.average","virtualdisk.numberreadaveraged.average"
|
||||
$Start = (Get-Date).AddMinutes($TimeRange)
|
||||
$stats = Get-Stat -Realtime -Stat $VMMetrics -Entity $VMs -Start $Start -Verbose:$False
|
||||
Write-Verbose "$(Get-Date -Format G) Create VM Stats completed"
|
||||
#endregion
|
||||
|
||||
#region: Creating HD-Tab
|
||||
Write-Verbose "$(Get-Date -Format G) Create HD Tab..."
|
||||
$hdTab = @{}
|
||||
foreach($hd in (Get-Harddisk -VM $VMs)){
|
||||
$controllerKey = $hd.Extensiondata.ControllerKey
|
||||
$controller = $hd.Parent.Extensiondata.Config.Hardware.Device | where{$_.Key -eq $controllerKey}
|
||||
$hdTab[$hd.Parent.Name + "/scsi" + $controller.BusNumber + ":" + $hd.Extensiondata.UnitNumber] = $hd.FileName.Split(']')[0].TrimStart('[')
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Create HD Tab completed"
|
||||
#endregion
|
||||
|
||||
#region: Creating Reports
|
||||
Write-Verbose "$(Get-Date -Format G) Create Report..."
|
||||
$reportPerf = @()
|
||||
$reportPerf = $stats | Group-Object -Property {$_.Entity.Name},Instance | %{
|
||||
New-Object PSObject -Property @{
|
||||
VM = $_.Values[0]
|
||||
Disk = $_.Values[1]
|
||||
IOPSWriteAvg = [math]::round( ($_.Group | `
|
||||
where{$_.MetricId -eq "virtualdisk.numberwriteaveraged.average"} | `
|
||||
Measure-Object -Property Value -Average).Average,2)
|
||||
IOPSReadAvg = [math]::round( ($_.Group | `
|
||||
where{$_.MetricId -eq "virtualdisk.numberreadaveraged.average"} | `
|
||||
Measure-Object -Property Value -Average).Average,2)
|
||||
Datastore = $hdTab[$_.Values[0] + "/"+ $_.Values[1]]
|
||||
}
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Create Report completed"
|
||||
#endregion
|
||||
|
||||
|
||||
}
|
||||
Else {
|
||||
Write-Error "VM $($_.Name) is Powered Off! Processing Skipped"
|
||||
}
|
||||
$reportPerf | Select-Object VM, Disk, Datastore, IOPSWriteAvg, IOPSReadAvg
|
||||
}
|
||||
|
||||
End {
|
||||
# none
|
||||
}
|
||||
|
||||
}
|
||||
@@ -8,14 +8,15 @@ function Recommend-Sizing {
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.11 ver 1.0 Base Release
|
||||
2016.11 ver 1.1 Optional Stats Collection.
|
||||
2016.11 ver 1.1 Optional Stats Collection
|
||||
2016.11 ver 1.2 VM Stats from Realtime Data and new Counters
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
http://www.lucd.info/2011/04/22/get-the-maximum-iops/
|
||||
https://communities.vmware.com/thread/485386
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: 5.5 U2
|
||||
vSphere Version: 5.5 U2, 6.0
|
||||
PowerCLI Version: PowerCLI 6.3 R1, PowerCLI 6.5 R1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2012 R2
|
||||
@@ -24,7 +25,7 @@ function Recommend-Sizing {
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function collects Basic vSphere Informations for a Hardware Sizing Recomamndation. Focus is in Compute Ressources.
|
||||
This Function collects Basic vSphere Informations for a Hardware Sizing Recommandation. Focus is in Compute Ressources.
|
||||
|
||||
.Example
|
||||
Recommend-Sizing -ClusterNames Cluster01, Cluster02 -Stats -StatsRange 60 -Verbose
|
||||
@@ -41,7 +42,7 @@ function Recommend-Sizing {
|
||||
.PARAMETER Stats
|
||||
Enables Stats Collection.
|
||||
|
||||
Warning: At the moment this is only tested and supported with vSphere 5.5!
|
||||
Warning: At the moment this is only fully tested with vSphere 5.5 and vSphere 6.5!
|
||||
|
||||
.PARAMETER StatsRange
|
||||
Time Range in Minutes for the Stats Collection.
|
||||
@@ -55,15 +56,15 @@ function Recommend-Sizing {
|
||||
param(
|
||||
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=0)]
|
||||
[Array] $ClusterNames,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=2)]
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=1, ParameterSetName = "Stats")]
|
||||
[switch] $Stats,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=2)]
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=2, ParameterSetName = "Stats")]
|
||||
[int] $StatsRange = 1440
|
||||
|
||||
)
|
||||
Begin {
|
||||
if ($Stats) {
|
||||
Write-Warning "Stats Collection enabled.`nAt the moment this is only tested and supported with vSphere 5.5"
|
||||
Write-Warning "Stats Collection requested.`nAt the moment this is only fully tested with vSphere 5.5 and vSphere 6.5"
|
||||
[int]$TimeRange = "-" + $StatsRange
|
||||
}
|
||||
|
||||
@@ -121,30 +122,38 @@ Process {
|
||||
#endregion
|
||||
|
||||
if ($Stats) {
|
||||
#region: Creating Disk Metrics
|
||||
Write-Verbose "$(Get-Date -Format G) Create $($Cluster.name) IOPS Metrics..."
|
||||
$DiskMetrics = "virtualDisk.numberReadAveraged.average","virtualDisk.numberWriteAveraged.average"
|
||||
$start = (Get-Date).AddMinutes($TimeRange)
|
||||
$DiskStats = Get-Stat -Stat $DiskMetrics -Entity $ClusterVMsPoweredOn -Start $start -Verbose:$False
|
||||
Write-Verbose "$(Get-Date -Format G) Create $($Cluster.name) IOPS Metrics completed"
|
||||
#region: Creating VM Stats
|
||||
Write-Verbose "$(Get-Date -Format G) Create $($Cluster.name) VM Stats..."
|
||||
$VMMetrics = "disk.numberwrite.summation","disk.numberread.summation","cpu.usage.average", "mem.usage.average"
|
||||
$Start = (Get-Date).AddMinutes($TimeRange)
|
||||
$VMStats = Get-Stat -Realtime -Stat $VMMetrics -Entity $ClusterVMsPoweredOn -Start $Start -Verbose:$False
|
||||
Write-Verbose "$(Get-Date -Format G) Create $($Cluster.name) VM Stats completed"
|
||||
#endregion
|
||||
|
||||
#region: Creating IOPS Reports
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) IOPS Report..."
|
||||
$reportDiskPerf = @()
|
||||
$reportDiskPerf = $DiskStats | Group-Object -Property {$_.Entity.Name},Instance | %{
|
||||
New-Object PSObject -Property @{
|
||||
IOPSMax = ($_.Group | `
|
||||
Group-Object -Property Timestamp | `
|
||||
%{$_.Group[0].Value + $_.Group[1].Value} | `
|
||||
Measure-Object -Maximum).Maximum
|
||||
#region: Creating VM Stats Report
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) VM Stats Report..."
|
||||
$ReportVMPerf = @()
|
||||
$ReportVMPerf = $VMStats | Group-Object -Property {$_.Entity.Name},Instance | %{
|
||||
New-Object PSObject -Property @{
|
||||
IOPSWriteAvg = ($_.Group | `
|
||||
where{$_.MetricId -eq "disk.numberwrite.summation"} | `
|
||||
Measure-Object -Property Value -Average).Average
|
||||
IOPSReadAvg = ($_.Group | `
|
||||
where{$_.MetricId -eq "disk.numberread.summation"} | `
|
||||
Measure-Object -Property Value -Average).Average
|
||||
CPUUsageAvg = ($_.Group | `
|
||||
where{$_.MetricId -eq "cpu.usage.average"} | `
|
||||
Measure-Object -Property Value -Average).Average
|
||||
MEMUsageAvg = ($_.Group | `
|
||||
where{$_.MetricId -eq "mem.usage.average"} | `
|
||||
Measure-Object -Property Value -Average).Average
|
||||
}
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) IOPS Report completed"
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) VM Stats Report completed"
|
||||
#endregion
|
||||
}
|
||||
else {
|
||||
Write-Verbose "$(Get-Date -Format G) Stats Cellocetion skipped..."
|
||||
Write-Verbose "$(Get-Date -Format G) Stats Collection skipped..."
|
||||
}
|
||||
|
||||
#region: Create VM Disk Space Report
|
||||
@@ -194,8 +203,10 @@ Process {
|
||||
SumVMDiskSpaceGB = [math]::round( ($reportDiskSpace | Measure-Object -Sum -Property CapacityGB).sum, 1 )
|
||||
SumDatastoreSpaceGB = [math]::round( ($DatastoreReport | Measure-Object -Sum -Property CapacityGB).sum, 1 )
|
||||
SumDatastoreUsedSpaceGB = [math]::round( ($DatastoreReport | Measure-Object -Sum -Property UsedSpaceGB).sum, 1 )
|
||||
SumMaxVMIOPS = [math]::round( ($reportDiskPerf | Measure-Object -Sum -Property IOPSMax).sum, 1 )
|
||||
AverageMaxVMIOPs = [math]::round( ($reportDiskPerf | Measure-Object -Average -Property IOPSMax).Average,1 )
|
||||
AverageVMIOPSWriteAvg = [math]::round( ($ReportVMPerf | Measure-Object -Average -Property IOPSWriteAvg).Average,1 )
|
||||
AverageVMIOPSReadAvg = [math]::round( ($ReportVMPerf | Measure-Object -Average -Property IOPSReadAvg).Average,1 )
|
||||
AverageVMCPUUsageAvg = "$([math]::round( ($ReportVMPerf | Measure-Object -Average -Property CPUUsageAvg).Average,1 )) %"
|
||||
AverageVMMEMUsageAvg = "$([math]::round( ($ReportVMPerf | Measure-Object -Average -Property MEMUsageAvg).Average,1 )) %"
|
||||
}
|
||||
$MyView += $SizingReport
|
||||
Write-Verbose "$(Get-Date -Format G) Process Global Report completed"
|
||||
|
||||
111
Modules/Set-CBT.psm1
Normal file
111
Modules/Set-CBT.psm1
Normal file
@@ -0,0 +1,111 @@
|
||||
function Set-CBT {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.11 ver 1.0 Base Release
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
http://wahlnetwork.com/2015/12/01/change-block-tracking-cbt-powercli/
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: 5.5 U2
|
||||
PowerCLI Version: PowerCLI 6.3 R1
|
||||
PowerShell Version: 4.0
|
||||
OS Version: Windows Server 2012 R2
|
||||
===========================================================================
|
||||
Keywords vSphere, ESXi, VM, Storage, CBT, Backup
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
This Function enables or disables CBT.
|
||||
|
||||
.Example
|
||||
Get-VN TST* | Set-CBT -DisableCBT
|
||||
|
||||
.Example
|
||||
Get-VN TST* | Set-CBT -EnableCBT
|
||||
|
||||
.PARAMETER DisableCBT
|
||||
Disables CBT for any VMs found with it enabled
|
||||
|
||||
.PARAMETER EnableCBT
|
||||
Enables CBT for any VMs found with it disabled
|
||||
|
||||
#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=$True, Position=0, HelpMessage = "VMs to process")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]] $myVMs,
|
||||
[Parameter(Mandatory = $False,ValueFromPipeline=$False, Position = 1, HelpMessage = "Enables CBT for any VMs found with it disabled", ParameterSetName = "EnableCBT")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[Switch]$EnableCBT,
|
||||
[Parameter(Mandatory = $False,ValueFromPipeline=$False, Position = 1, HelpMessage = "Disables CBT for any VMs found with it enabled", ParameterSetName = "DisableCBT")]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[Switch]$DisableCBT
|
||||
)
|
||||
Process {
|
||||
|
||||
$vmconfigspec = New-Object -TypeName VMware.Vim.VirtualMachineConfigSpec
|
||||
Write-Verbose -Message "Walking through given VMs"
|
||||
foreach($myVM in $myVMs)
|
||||
{
|
||||
if ($DisableCBT -and $myVM.ExtensionData.Config.ChangeTrackingEnabled -eq $true -and $myVM.ExtensionData.Snapshot -eq $null)
|
||||
{
|
||||
try
|
||||
{
|
||||
Write-Verbose -Message "Reconfiguring $($myVM.name) to disable CBT" -Verbose
|
||||
$vmconfigspec.ChangeTrackingEnabled = $false
|
||||
$myVM.ExtensionData.ReconfigVM($vmconfigspec)
|
||||
|
||||
if ($myVM.PowerState -eq "PoweredOn" ) {
|
||||
Write-Verbose -Message "Creating a snapshot on $($myVM.name) to clear CBT file" -Verbose
|
||||
$SnapShot = New-Snapshot -VM $myVM -Name "CBT Cleanup"
|
||||
|
||||
Write-Verbose -Message "Removing snapshot on $($myVM.name)" -Verbose
|
||||
$SnapShot| Remove-Snapshot -Confirm:$false
|
||||
}
|
||||
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw $myVM
|
||||
}
|
||||
}
|
||||
elseif ($EnableCBT -and $myVM.ExtensionData.Config.ChangeTrackingEnabled -eq $false -and $myVM.ExtensionData.Snapshot -eq $null)
|
||||
{
|
||||
Write-Verbose -Message "Reconfiguring $($myVM.name) to enable CBT" -Verbose
|
||||
$vmconfigspec.ChangeTrackingEnabled = $true
|
||||
$myVM.ExtensionData.ReconfigVM($vmconfigspec)
|
||||
|
||||
if ($myVM.PowerState -eq "PoweredOn" ) {
|
||||
Write-Verbose -Message "Creating a snapshot on $($myVM.name) to Create CBT file" -Verbose
|
||||
$SnapShot = New-Snapshot -VM $myVM -Name "CBT Cleanup"
|
||||
|
||||
Write-Verbose -Message "Removing snapshot on $($myVM.name)" -Verbose
|
||||
$SnapShot | Remove-Snapshot -Confirm:$false
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if ($myVM.ExtensionData.Snapshot -ne $null -and $EnableCBT)
|
||||
{
|
||||
Write-Warning -Message "Skipping $($myVM.name) - Snapshots found"
|
||||
}
|
||||
elseif ($myVM.ExtensionData.Snapshot -ne $null -and $DisableCBT)
|
||||
{
|
||||
Write-Warning -Message "Skipping $($myVM.name) - Snapshots found"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
99
Modules/Start-UNMAP.psm1
Normal file
99
Modules/Start-UNMAP.psm1
Normal file
@@ -0,0 +1,99 @@
|
||||
function Start-UNMAP {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Process SCSI UNMAP on VMware Datastores
|
||||
|
||||
.DESCRIPTION
|
||||
This Function will process SCSI UNMAP on VMware Datastores via ESXCLI -V2
|
||||
|
||||
.Example
|
||||
Start-UNMAP -ClusterName myCluster -DSWildcard *RAID5*
|
||||
|
||||
.Example
|
||||
Start-UNMAP -ClusterName myCluster -DSWildcard *RAID5* -Verbose -WhatIf
|
||||
|
||||
.Notes
|
||||
NAME: Start-UNMAP.psm1
|
||||
AUTHOR: Markus Kraus
|
||||
LASTEDIT: 23.09.2016
|
||||
VERSION: 1.0
|
||||
KEYWORDS: VMware, vSphere, ESXi, SCSI, VAAI, UNMAP
|
||||
|
||||
.Link
|
||||
http://mycloudrevolution.com/
|
||||
|
||||
#Requires PS -Version 4.0
|
||||
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="6.3.0.0"}
|
||||
#>
|
||||
|
||||
[CmdletBinding(SupportsShouldProcess = $true,ConfirmImpact='High')]
|
||||
param(
|
||||
[Parameter(Mandatory=$true, Position=0)]
|
||||
[String]$ClusterName,
|
||||
[Parameter(Mandatory=$true, Position=1)]
|
||||
[String]$DSWildcard
|
||||
)
|
||||
Process {
|
||||
$Validate = $true
|
||||
#region: PowerCLI Session Timeout
|
||||
Write-Verbose "Set Session Timeout ..."
|
||||
$initialTimeout = (Get-PowerCLIConfiguration -Scope Session).WebOperationTimeoutSeconds
|
||||
Set-PowerCLIConfiguration -Scope Session -WebOperationTimeoutSeconds -1 -Confirm:$False | Out-Null
|
||||
#endregion
|
||||
|
||||
#region: Get Cluster
|
||||
$Cluster = Get-Cluster -Name $ClusterName -ErrorAction SilentlyContinue
|
||||
Write-Verbose "vSphere Cluster: $Cluster"
|
||||
if (!$Cluster){Write-Error "No Cluster found!"; $Validate = $false}
|
||||
#endregion
|
||||
|
||||
#region: Get Hosts
|
||||
$ClusterHosts = $Cluster | Get-VMHost -ErrorAction SilentlyContinue | where {$_.ConnectionState -eq "Connected" -and $_.PowerState -eq "PoweredOn"}
|
||||
Write-Verbose "vSphere Cluster Hosts: $ClusterHosts"
|
||||
if (!$ClusterHosts){Write-Error "No Hosts found!"; $Validate = $false}
|
||||
#endregion
|
||||
|
||||
#region: Get Datastores
|
||||
$ClusterDataStores = $Cluster | Get-Datastore -ErrorAction SilentlyContinue | where {$_.Name -like $DSWildcard -and $_.State -eq "Available" -and $_.Accessible -eq "True"}
|
||||
Write-Verbose "vSphere Cluster Datastores: $ClusterDataStores"
|
||||
if (!$ClusterDataStores){Write-Error "No Datastores found!"; $Validate = $false}
|
||||
#endregion
|
||||
|
||||
#region: Process Datastores
|
||||
if ($Validate -eq $true) {
|
||||
Write-Verbose "Starting Loop..."
|
||||
foreach ($ClusterDataStore in $ClusterDataStores) {
|
||||
Write-Verbose "vSphere Datastore to Process: $ClusterDataStore"
|
||||
$myHost = $ClusterHosts[(Get-Random -Maximum ($ClusterHosts).count)]
|
||||
Write-Verbose "vSphere Host to Process: $myHost"
|
||||
$esxcli2 = $myHost | Get-ESXCLI -V2
|
||||
$arguments = $esxcli2.storage.vmfs.unmap.CreateArgs()
|
||||
$arguments.volumelabel = $ClusterDataStore
|
||||
$arguments.reclaimunit = "256"
|
||||
if ($PSCmdlet.ShouldProcess( $ClusterDataStore,"Starting UNMAP on $myHost")) {
|
||||
$stopwatch = [System.Diagnostics.Stopwatch]::StartNew()
|
||||
try {
|
||||
Write-Output "Starting UNMAP for $ClusterDataStore on $myHost..."
|
||||
$esxcli2.storage.vmfs.unmap.Invoke($arguments)
|
||||
}
|
||||
catch {
|
||||
Write-Output "A Error occured: " "" $error[0] ""
|
||||
}
|
||||
$stopwatch.Stop()
|
||||
Write-Output "UNMAP duration: $($stopwatch.Elapsed.Minutes)"
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
Write-Error "Validation Failed. Processing Loop Skipped!"
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region: Revert PowerCLI Session Timeout
|
||||
Write-Verbose "Revert Session Timeout ..."
|
||||
Set-PowerCLIConfiguration -Scope Session -WebOperationTimeoutSeconds $initialTimeout -Confirm:$False | Out-Null
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
413
Modules/VCHA.psm1
Normal file
413
Modules/VCHA.psm1
Normal file
@@ -0,0 +1,413 @@
|
||||
Function Get-VCHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the VCHA Configuration which provides you with
|
||||
the current state, mode as well as the IP Addresses of the Active,
|
||||
Passive & Witness Node. This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to return VCHA Configuration
|
||||
.EXAMPLE
|
||||
Get-VCHAConfig
|
||||
#>
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$vcHAConfig = $vcHAClusterConfig.getVchaConfig()
|
||||
|
||||
$vcHAState = $vcHAConfig.State
|
||||
switch($vcHAState) {
|
||||
configured {
|
||||
$activeIp = $vcHAConfig.FailoverNodeInfo1.ClusterIpSettings.Ip.IpAddress
|
||||
$passiveIp = $vcHAConfig.FailoverNodeInfo2.ClusterIpSettings.Ip.IpAddress
|
||||
$witnessIp = $vcHAConfig.WitnessNodeInfo.IpSettings.Ip.IpAddress
|
||||
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
$vcHAMode = $vcHAClusterManager.getClusterMode()
|
||||
|
||||
Write-Host ""
|
||||
Write-Host -NoNewline -ForegroundColor Green "VCHA State: "
|
||||
Write-Host -ForegroundColor White "$vcHAState"
|
||||
Write-Host -NoNewline -ForegroundColor Green " VCHA Mode: "
|
||||
Write-Host -ForegroundColor White "$vcHAMode"
|
||||
Write-Host -NoNewline -ForegroundColor Green " ActiveIP: "
|
||||
Write-Host -ForegroundColor White "$activeIp"
|
||||
Write-Host -NoNewline -ForegroundColor Green " PassiveIP: "
|
||||
Write-Host -ForegroundColor White "$passiveIp"
|
||||
Write-Host -NoNewline -ForegroundColor Green " WitnessIP: "
|
||||
Write-Host -ForegroundColor White "$witnessIp`n"
|
||||
;break
|
||||
}
|
||||
invalid { Write-Host -ForegroundColor Red "VCHA State is in invalid state ...";break}
|
||||
notConfigured { Write-Host "VCHA is not configured";break}
|
||||
prepared { Write-Host "VCHA is being prepared, please try again in a little bit ...";break}
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VCHAClusterHealth {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the VCHA Cluster Health which provides more info
|
||||
on each of the individual. This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to return VCHA Cluster Health
|
||||
.EXAMPLE
|
||||
Get-VCHAClusterHealth
|
||||
#>
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$vcHAConfig = $vcHAClusterConfig.getVchaConfig()
|
||||
$vcHAState = $vcHAConfig.State
|
||||
|
||||
switch($vcHAState) {
|
||||
invalid { Write-Host -ForegroundColor Red "VCHA State is in invalid state ...";break}
|
||||
notConfigured { Write-Host "VCHA is not configured";break}
|
||||
prepared { Write-Host "VCHA is being prepared ...";break}
|
||||
configured {
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
$healthInfo = $vcHAClusterManager.GetVchaClusterHealth()
|
||||
|
||||
$vcClusterState = $healthInfo.RuntimeInfo.ClusterState
|
||||
$nodeState = $healthInfo.RuntimeInfo.NodeInfo
|
||||
|
||||
Write-Host ""
|
||||
Write-Host -NoNewline -ForegroundColor Green "VCHA Cluster State: "
|
||||
Write-Host -ForegroundColor White "$vcClusterState"
|
||||
Write-Host -NoNewline -ForegroundColor Green "VCHA Node Information: "
|
||||
$nodeState | Select NodeIp, NodeRole, NodeState
|
||||
;break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Set-VCHAClusterMode {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function allows you to set the mode of the VCHA Cluster whether
|
||||
that is Enabled, Disabled or in Maintenance Mode. This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to set VCHA Cluster Mode
|
||||
.EXAMPLE
|
||||
Set-VCHAClusterMode -Enabled $true
|
||||
.EXAMPLE
|
||||
Set-VCHAClusterMode -Disabled $true
|
||||
.EXAMPLE
|
||||
Set-VCHAClusterMode -Maintenance $true
|
||||
#>
|
||||
param(
|
||||
[Switch]$Enabled,
|
||||
[Switch]$Disabled,
|
||||
[Switch]$Maintenance
|
||||
)
|
||||
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
|
||||
if($Enabled) {
|
||||
Write-Host "Setting VCHA Cluster to Enabled ..."
|
||||
$task = $vcHAClusterManager.setClusterMode_Task("enabled")
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
} elseIf($Maintenance) {
|
||||
Write-Host "Setting VCHA Cluster to Maintenance ..."
|
||||
$task = $vcHAClusterManager.setClusterMode_Task("maintenance")
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
} elseIf($Disabled) {
|
||||
Write-Host "`nSetting VCHA Cluster to Disabled ...`n"
|
||||
$task = $vcHAClusterManager.setClusterMode_Task("disabled")
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
}
|
||||
}
|
||||
|
||||
Function New-VCHABasicConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function allows you create a new "Basic" VCHA Cluster, it does not
|
||||
cover the "Advanced" use case. You will need to ensure that you have a
|
||||
"Self Managed" vCenter Server before attempting this workflow.
|
||||
This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to create "Basic" VCHA Cluster
|
||||
.PARAMETER VCSAVM
|
||||
The name of the vCenter Server Appliance (VCSA) in which you wish to enable VCHA on (must be self-managed)
|
||||
.PARAMETER HANetwork
|
||||
The name of the Virtual Portgroup or Distributed Portgroup used for the HA Network
|
||||
.PARAMETER ActiveHAIp
|
||||
The IP Address for the Active VCSA node
|
||||
.PARAMETER ActiveNetmask
|
||||
The Netmask for the Active VCSA node
|
||||
.PARAMETER PassiveHAIp
|
||||
The IP Address for the Passive VCSA node
|
||||
.PARAMETER PassiveNetmask
|
||||
The Netmask for the Passive VCSA node
|
||||
.PARAMETER WitnessHAIp
|
||||
The IP Address for the Witness VCSA node
|
||||
.PARAMETER WitnessNetmask
|
||||
The Netmask for the Witness VCSA node
|
||||
.PARAMETER PassiveDatastore
|
||||
The name of the datastore to deploy the Passive node to
|
||||
.PARAMETER WitnessDatastore
|
||||
The name of the datastore to deploy the Witness node to
|
||||
.PARAMETER VCUsername
|
||||
The VCSA username (e.g. administrator@vghetto.local)
|
||||
.PARAMETER VCPassword
|
||||
The VCSA password
|
||||
.EXAMPLE
|
||||
New-VCHABasicConfig -VCSAVM "vcenter65-1" -HANetwork "DVPG-VCHA-Network" `
|
||||
-ActiveHAIp 192.168.1.70 `
|
||||
-ActiveNetmask 255.255.255.0 `
|
||||
-PassiveHAIp 192.168.1.71 `
|
||||
-PassiveNetmask 255.255.255.0 `
|
||||
-WitnessHAIp 192.168.1.72 `
|
||||
-WitnessNetmask 255.255.255.0 `
|
||||
-PassiveDatastore "vsanDatastore" `
|
||||
-WitnessDatastore "vsanDatastore" `
|
||||
-VCUsername "administrator@vghetto.local" `
|
||||
-VCPassword "VMware1!"
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$VCSAVM,
|
||||
[String]$HANetwork,
|
||||
[String]$ActiveHAIp,
|
||||
[String]$ActiveNetmask,
|
||||
[String]$PassiveHAIp,
|
||||
[String]$PassiveNetmask,
|
||||
[String]$PassiveDatastore,
|
||||
[String]$WitnessHAIp,
|
||||
[String]$WitnessNetmask,
|
||||
[String]$WitnessDatastore,
|
||||
# Crappy Implementation but need to research more into using PSH Credential
|
||||
[String]$VCUsername,
|
||||
[String]$VCPassword
|
||||
)
|
||||
|
||||
$VCSAVMView = Get-View -ViewType VirtualMachine -Filter @{"name"=$VCSAVM}
|
||||
if($VCSAVMView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Virtual Machine $VCSAVM"
|
||||
return
|
||||
}
|
||||
|
||||
$HANetworkView = Get-View -ViewType Network -Filter @{"name"=$HANetwork}
|
||||
if($HANetworkView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Network $HANetwork"
|
||||
return
|
||||
}
|
||||
|
||||
$PassiveDatastoreView = Get-View -ViewType Datastore -Filter @{"name"=$PassiveDatastore}
|
||||
if($PassiveDatastoreView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Passive Datastore $PassiveDatastore"
|
||||
return
|
||||
}
|
||||
|
||||
$WitnessDatastoreView = Get-View -ViewType Datastore -Filter @{"name"=$WitnessDatastore}
|
||||
if($WitnessDatastoreView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to find Witness Datastore $WitnessDatastore"
|
||||
return
|
||||
}
|
||||
|
||||
$vcIP = $VCSAVMView.Guest.IpAddress
|
||||
if($vcIP -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Error: Unable to automatically retrieve the IP Address of $VCSAVM which is needed to use this function"
|
||||
return
|
||||
}
|
||||
|
||||
# Retrieve Source VC SSL Thumbprint
|
||||
$vcurl = "https://$vcIP"
|
||||
add-type @"
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
|
||||
public class IDontCarePolicy : ICertificatePolicy {
|
||||
public IDontCarePolicy() {}
|
||||
public bool CheckValidationResult(
|
||||
ServicePoint sPoint, X509Certificate cert,
|
||||
WebRequest wRequest, int certProb) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
"@
|
||||
[System.Net.ServicePointManager]::CertificatePolicy = new-object IDontCarePolicy
|
||||
# Need to do simple GET connection for this method to work
|
||||
Invoke-RestMethod -Uri $VCURL -Method Get | Out-Null
|
||||
|
||||
$endpoint_request = [System.Net.Webrequest]::Create("$vcurl")
|
||||
# Get Thumbprint + add colons for a valid Thumbprint
|
||||
$vcSSLThumbprint = ($endpoint_request.ServicePoint.Certificate.GetCertHashString()) -replace '(..(?!$))','$1:'
|
||||
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$spec = New-Object VMware.Vim.VchaClusterDeploymentSpec
|
||||
|
||||
$activeNetworkConfig = New-Object VMware.Vim.ClusterNetworkConfigSpec
|
||||
$activeNetworkConfig.NetworkPortGroup = $HANetworkView.MoRef
|
||||
$ipSettings = New-Object Vmware.Vim.CustomizationIPSettings
|
||||
$ipSettings.SubnetMask = $ActiveNetmask
|
||||
$activeIpSpec = New-Object VMware.Vim.CustomizationFixedIp
|
||||
$activeIpSpec.IpAddress = $ActiveHAIp
|
||||
$ipSettings.Ip = $activeIpSpec
|
||||
$activeNetworkConfig.IpSettings = $ipSettings
|
||||
$spec.ActiveVcNetworkConfig = $activeNetworkConfig
|
||||
|
||||
$activeVCConfig = New-Object Vmware.Vim.SourceNodeSpec
|
||||
$activeVCConfig.ActiveVc = $VCSAVMView.MoRef
|
||||
$serviceLocator = New-Object Vmware.Vim.ServiceLocator
|
||||
$credential = New-Object VMware.Vim.ServiceLocatorNamePassword
|
||||
$credential.username = $VCUsername
|
||||
$credential.password = $VCPassword
|
||||
$serviceLocator.Credential = $credential
|
||||
$serviceLocator.InstanceUuid = $global:DefaultVIServer.InstanceUuid
|
||||
$serviceLocator.Url = $vcurl
|
||||
$serviceLocator.SslThumbprint = $vcSSLThumbprint
|
||||
$activeVCConfig.ManagementVc = $serviceLocator
|
||||
$spec.ActiveVcSpec = $activeVCConfig
|
||||
|
||||
$passiveSpec = New-Object VMware.Vim.PassiveNodeDeploymentSpec
|
||||
$passiveSpec.Folder = (Get-View (Get-Folder vm)).MoRef
|
||||
$passiveIpSettings = New-object Vmware.Vim.CustomizationIPSettings
|
||||
$passiveIpSettings.SubnetMask = $passiveNetmask
|
||||
$passiveIpSpec = New-Object VMware.Vim.CustomizationFixedIp
|
||||
$passiveIpSpec.IpAddress = $passiveHAIp
|
||||
$passiveIpSettings.Ip = $passiveIpSpec
|
||||
$passiveSpec.IpSettings = $passiveIpSettings
|
||||
$passiveSpec.NodeName = $VCSAVMView.Name + "-Passive"
|
||||
$passiveSpec.datastore = $PassiveDatastoreView.MoRef
|
||||
$spec.PassiveDeploymentSpec = $passiveSpec
|
||||
|
||||
$witnessSpec = New-Object VMware.Vim.NodeDeploymentSpec
|
||||
$witnessSpec.Folder = (Get-View (Get-Folder vm)).MoRef
|
||||
$witnessSpec.NodeName = $VCSAVMView.Name + "-Witness"
|
||||
$witnessIpSettings = New-object Vmware.Vim.CustomizationIPSettings
|
||||
$witnessIpSettings.SubnetMask = $witnessNetmask
|
||||
$witnessIpSpec = New-Object VMware.Vim.CustomizationFixedIp
|
||||
$witnessIpSpec.IpAddress = $witnessHAIp
|
||||
$witnessIpSettings.Ip = $witnessIpSpec
|
||||
$witnessSpec.IpSettings = $witnessIpSettings
|
||||
$witnessSpec.datastore = $WitnessDatastoreView.MoRef
|
||||
$spec.WitnessDeploymentSpec = $witnessSpec
|
||||
|
||||
Write-Host "`nDeploying VCHA Cluster ...`n"
|
||||
$task = $vcHAClusterConfig.deployVcha_Task($spec)
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task -Verbose
|
||||
}
|
||||
|
||||
Function Remove-VCHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Date: Nov 20, 2016
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function allows you destroy a VCHA Cluster. In addition, you have
|
||||
the option to specify whether you would like both the Passive & Witness
|
||||
Virtual Machines be deleted after the VCHA Cluster has been destroyed.
|
||||
This is only available on VCSA 6.5 (vSphere 6.5 or greater)
|
||||
.DESCRIPTION
|
||||
Function to destroy a VCHA Cluster Mode
|
||||
.EXAMPLE
|
||||
Remove-VCHAConfig
|
||||
.EXAMPLE
|
||||
Remove-VCHAConfig -Confirm:$false
|
||||
.EXAMPLE
|
||||
Remove-VCHAConfig -DeleteVM $true -Confirm:$false
|
||||
.NOTES
|
||||
Before you can destroy a VCHA Cluster, you must make sure it is first
|
||||
disabled. Run the Set-VCHAClusterMode -Disabled $true to do so
|
||||
#>
|
||||
param(
|
||||
[Boolean]$Confirm=$true,
|
||||
[Switch]$DeleteVM=$false
|
||||
)
|
||||
|
||||
$Verified = $false
|
||||
if($Confirm -eq $true) {
|
||||
Write-Host -ForegroundColor Yellow "`nDo you want to destroy VCHA Cluster?"
|
||||
$answer = Read-Host -Prompt "Do you accept (Y or N)"
|
||||
if($answer -eq "Y" -or $answer -eq "y") {
|
||||
$Verified = $true
|
||||
}
|
||||
} else {
|
||||
$Verified = $true
|
||||
}
|
||||
|
||||
if($Verified) {
|
||||
$vcHAClusterManager = Get-View failoverClusterManager
|
||||
$vcHAMode = $vcHAClusterManager.getClusterMode()
|
||||
|
||||
if($vcHAMode -ne "disabled") {
|
||||
Write-Host -ForegroundColor Yellow "To destroy VCHA Cluster, you must first set the VCHA Cluster Mode to `"Disabled`""
|
||||
Exit
|
||||
}
|
||||
|
||||
# Query BIOS UUID of the Passive/Witness to be able to delete
|
||||
if($DeleteVM) {
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
$vcHAConfig = $vcHAClusterConfig.getVchaConfig()
|
||||
$passiveBiosUUID = $vcHAConfig.FailoverNodeInfo2.biosUuid
|
||||
$witnessBiosUUID = $vcHAConfig.WitnessNodeInfo.biosUuid
|
||||
}
|
||||
|
||||
$vcHAClusterConfig = Get-View failoverClusterConfigurator
|
||||
|
||||
Write-Host "Destroying VCHA Cluster ..."
|
||||
$task = $vcHAClusterConfig.destroyVcha_Task()
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task
|
||||
|
||||
# After VCHA Cluster has been destroyed, we can now delete the VMs we had queried earlier
|
||||
if($DeleteVM) {
|
||||
if($passiveBiosUUID -ne $null -and $witnessBiosUUID -ne $null) {
|
||||
$searchIndex = Get-View searchIndex
|
||||
|
||||
$passiveVM = $searchIndex.FindByUuid($null,$passiveBiosUUID,$true,$null)
|
||||
$witnessVM = $searchIndex.FindByUuid($null,$witnessBiosUUID,$true,$null)
|
||||
|
||||
if($passiveVM -ne $null -and $witnessVM -ne $null) {
|
||||
Write-Host "Powering off & deleting Passive VM ..."
|
||||
Stop-VM -VM (Get-View $passiveVM).Name -Confirm:$false | Out-Null
|
||||
Remove-VM (Get-View $passiveVM).Name -DeletePermanently -Confirm:$false
|
||||
Write-Host "Powering off & deleting Witness VM ..."
|
||||
Stop-VM -VM (Get-View $witnessVM).Name -Confirm:$false | Out-Null
|
||||
Remove-VM (Get-View $witnessVM).Name -DeletePermanently -Confirm:$false
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
7
Modules/VMware.VMEncryption/README.md
Normal file
7
Modules/VMware.VMEncryption/README.md
Normal file
@@ -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.
|
||||
BIN
Modules/VMware.VMEncryption/VMware.VMEncryption.psd1
Normal file
BIN
Modules/VMware.VMEncryption/VMware.VMEncryption.psd1
Normal file
Binary file not shown.
2045
Modules/VMware.VMEncryption/VMware.VMEncryption.psm1
Normal file
2045
Modules/VMware.VMEncryption/VMware.VMEncryption.psm1
Normal file
File diff suppressed because it is too large
Load Diff
93
Modules/apply-hardening.psm1
Normal file
93
Modules/apply-hardening.psm1
Normal file
@@ -0,0 +1,93 @@
|
||||
function Apply-Hardening {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.11 ver 2.0 Base Release
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
|
||||
===========================================================================
|
||||
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
|
||||
Keyword: VM, Hardening, Security
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
Applys a set of Hardening options to your VMs
|
||||
|
||||
.Example
|
||||
Get-VM TST* | Apply-Hardening
|
||||
|
||||
.Example
|
||||
$SampleVMs = Get-VM "TST*"
|
||||
Apply-Hardening -VMs $SampleVMs
|
||||
|
||||
.PARAMETER VMs
|
||||
Specify the VMs
|
||||
|
||||
|
||||
#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=$True,
|
||||
Position=0)]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.InventoryItemImpl[]]
|
||||
$VMs
|
||||
)
|
||||
|
||||
Process {
|
||||
#region: Create Options
|
||||
$ExtraOptions = @{
|
||||
"isolation.tools.diskShrink.disable"="true";
|
||||
"isolation.tools.diskWiper.disable"="true";
|
||||
"isolation.tools.copy.disable"="true";
|
||||
"isolation.tools.paste.disable"="true";
|
||||
"isolation.tools.dnd.disable"="true";
|
||||
"isolation.tools.setGUIOptions.enable"="false";
|
||||
"log.keepOld"="10";
|
||||
"log.rotateSize"="100000"
|
||||
"RemoteDisplay.maxConnections"="2";
|
||||
"RemoteDisplay.vnc.enabled"="false";
|
||||
|
||||
}
|
||||
if ($DebugPreference -eq "Inquire") {
|
||||
Write-Output "VM Hardening Options:"
|
||||
$ExtraOptions | Format-Table -AutoSize
|
||||
}
|
||||
|
||||
$VMConfigSpec = New-Object VMware.Vim.VirtualMachineConfigSpec
|
||||
|
||||
Foreach ($Option in $ExtraOptions.GetEnumerator()) {
|
||||
$OptionValue = New-Object VMware.Vim.optionvalue
|
||||
$OptionValue.Key = $Option.Key
|
||||
$OptionValue.Value = $Option.Value
|
||||
$VMConfigSpec.extraconfig += $OptionValue
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region: Apply Options
|
||||
ForEach ($VM in $VMs){
|
||||
$VMv = Get-VM $VM | Get-View
|
||||
$state = $VMv.Summary.Runtime.PowerState
|
||||
Write-Output "...Starting Reconfiguring VM: $VM "
|
||||
$TaskConf = ($VMv).ReconfigVM_Task($VMConfigSpec)
|
||||
if ($state -eq "poweredOn") {
|
||||
Write-Output "...Migrating VM: $VM "
|
||||
$TaskMig = $VMv.MigrateVM_Task($null, $_.Runtime.Host, 'highPriority', $null)
|
||||
}
|
||||
}
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
108
Scripts/DatastoreSIOCStatistics.ps1
Normal file
108
Scripts/DatastoreSIOCStatistics.ps1
Normal file
@@ -0,0 +1,108 @@
|
||||
function Get-DatastoreSIOCStatCollection {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Gathers information on the status of SIOC statistics collection for a datastore
|
||||
.DESCRIPTION
|
||||
Will provide the status on a datastore's SIOC statistics collection
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy, thatcouldbeaproblem.com
|
||||
.PARAMETER Datastore
|
||||
Datastore to be ran against
|
||||
.EXAMPLE
|
||||
Get-DatastoreSIOCStatCollection -Datastore ExampleDatastore
|
||||
Retreives the status of SIOC statistics collection for the provided datastore
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
$Datastore
|
||||
)
|
||||
|
||||
Process {
|
||||
|
||||
#Collect information about the desired datastore/s and verify existance
|
||||
$ds = Get-Datastore $datastore -warningaction silentlycontinue -erroraction silentlycontinue
|
||||
if (!$ds) {Write-Warning -Message "No Datastore found"}
|
||||
else {
|
||||
|
||||
$report = @()
|
||||
|
||||
#Loops through each datastore provided and feeds back information about the SIOC Statistics Collection status
|
||||
foreach ($item in $ds) {
|
||||
|
||||
$tempitem = "" | select Name,SIOCStatCollection
|
||||
$tempitem.Name = $item.Name
|
||||
$tempitem.SIOCStatCollection = $item.ExtensionData.IormConfiguration.statsCollectionEnabled
|
||||
$report += $tempitem
|
||||
|
||||
}
|
||||
|
||||
#Returns the output to the user
|
||||
return $report
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
function Set-DatastoreSIOCStatCollection {
|
||||
<#
|
||||
.SYNOPSIS
|
||||
Configures the status of SIOC statistics collection for a datastore
|
||||
.DESCRIPTION
|
||||
Will modify the status on a datastore's SIOC statistics collection
|
||||
.NOTES
|
||||
Author: Kyle Ruddy, @kmruddy, thatcouldbeaproblem.com
|
||||
.PARAMETER Datastore
|
||||
Datastore to be ran against
|
||||
.EXAMPLE
|
||||
Set-DatastoreSIOCStatCollection -Datastore ExampleDatastore -Enable
|
||||
Enables SIOC statistics collection for the provided datastore
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess)]
|
||||
param(
|
||||
[Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true)]
|
||||
$Datastore,
|
||||
[Switch]$Enable,
|
||||
[Switch]$Disable
|
||||
)
|
||||
|
||||
Process {
|
||||
|
||||
#Collect information about the desired datastore/s and verify existance
|
||||
$ds = Get-Datastore $datastore -warningaction silentlycontinue -erroraction silentlycontinue
|
||||
if (!$ds) {Write-Warning -Message "No Datastore found"}
|
||||
else {
|
||||
|
||||
$report = @()
|
||||
|
||||
#Loops through each datastore provided and modifies the SIOC Statistics Collection status
|
||||
foreach ($dsobj in $ds) {
|
||||
|
||||
$_this = Get-View -id 'StorageResourceManager-StorageResourceManager'
|
||||
$spec = New-Object vmware.vim.storageiormconfigspec
|
||||
|
||||
if ($Enable) {
|
||||
|
||||
$spec.statsCollectionEnabled = $true
|
||||
|
||||
} elseif ($Disable) {
|
||||
|
||||
$spec.statsCollectionEnabled = $false
|
||||
|
||||
}
|
||||
|
||||
$_this.ConfigureDatastoreIORM_Task($dsobj.ExtensionData.MoRef,$spec) | out-null
|
||||
start-sleep -s 1
|
||||
$report += Get-View -Id $dsobj.ExtensionData.MoRef -Property Name,Iormconfiguration.statsCollectionEnabled | select Name,@{N='SIOCStatCollection';E={$_.Iormconfiguration.statsCollectionEnabled}}
|
||||
|
||||
}
|
||||
|
||||
#Returns the output to the user
|
||||
return $report
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
28
Scripts/Home Lab/Home Lab Delete settings.ps1
Normal file
28
Scripts/Home Lab/Home Lab Delete settings.ps1
Normal file
@@ -0,0 +1,28 @@
|
||||
$ESXIP = "192.168.1.201"
|
||||
$ESXUser = "root"
|
||||
$ESXPWD = "VMware1!"
|
||||
|
||||
Connect-viserver $esxip -user $ESXUser -pass $ESXPWD
|
||||
|
||||
#Leaving confirm off just in case someone happens to be connected to more than one vCenter/Host!
|
||||
Get-VM | Stop-VM
|
||||
Get-VM | Remove-VM
|
||||
|
||||
$ESXCLI = Get-EsxCli -v2 -VMHost (get-VMHost)
|
||||
$esxcli.vsan.cluster.leave.invoke()
|
||||
|
||||
$VSANDisks = $esxcli.storage.core.device.list.invoke() | Where {$_.isremovable -eq "false"} | Sort size
|
||||
$Performance = $VSANDisks[0]
|
||||
$Capacity = $VSANDisks[1]
|
||||
|
||||
$removal = $esxcli.vsan.storage.remove.CreateArgs()
|
||||
$removal.ssd = $performance.Device
|
||||
$esxcli.vsan.storage.remove.Invoke($removal)
|
||||
|
||||
$capacitytag = $esxcli.vsan.storage.tag.remove.CreateArgs()
|
||||
$capacitytag.disk = $Capacity.Device
|
||||
$capacitytag.tag = "capacityFlash"
|
||||
$esxcli.vsan.storage.tag.remove.Invoke($capacitytag)
|
||||
|
||||
Set-VMHostSysLogServer $null
|
||||
Remove-VMHostNtpServer (Get-VMHostNtpServer) -Confirm:$false
|
||||
215
Scripts/Home Lab/Home Lab Deployment.ps1
Normal file
215
Scripts/Home Lab/Home Lab Deployment.ps1
Normal file
@@ -0,0 +1,215 @@
|
||||
# ESX Start Host deployment Settings
|
||||
$ESXIP = "192.168.1.201"
|
||||
$ESXUser = "root"
|
||||
$ESXPWD = "VMware1!"
|
||||
|
||||
# VCSA Configuration
|
||||
$VCSACDDrive = "D:\"
|
||||
$SSODomainName = "corp.local"
|
||||
$VCNAME = "VC01"
|
||||
$VCUser = "Administrator@$SSODomainName"
|
||||
$VCPass = "VMware1!"
|
||||
$VCIP = "192.168.1.200"
|
||||
$VCDNS = "192.168.1.1"
|
||||
$VCGW = "192.168.1.1"
|
||||
$VCNetPrefix = "24"
|
||||
$VCSADeploymentSize = "tiny"
|
||||
|
||||
# vCenter Configuration
|
||||
$SSOSiteName = "Site01"
|
||||
$datacenter = "DC01"
|
||||
$cluster = "Cluster01"
|
||||
$ntpserver = "pool.ntp.org"
|
||||
|
||||
# VSAN Configuration
|
||||
$VSANPolicy = '(("hostFailuresToTolerate" i1) ("forceProvisioning" i1))'
|
||||
$VMKNetforVSAN = "Management Network"
|
||||
|
||||
# General Settings
|
||||
$verboseLogFile = "$ENV:Temp\vsphere65-NUC-lab-deployment.log"
|
||||
|
||||
# End of configuration
|
||||
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"
|
||||
$logMessage = "[$timeStamp] $message"
|
||||
$logMessage | Out-File -Append -LiteralPath $verboseLogFile
|
||||
}
|
||||
|
||||
$StartTime = Get-Date
|
||||
|
||||
Write-Host "Writing Log files to $verboselogfile" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
|
||||
If (-not (Test-Path "$($VCSACDDrive)vcsa-cli-installer\win32\vcsa-deploy.exe")){
|
||||
Write-Host "VCSA media not found at $($VCSACDDrive) please mount it and try again"
|
||||
return
|
||||
}
|
||||
My-Logger "Connecting to ESXi Host: $ESXIP ..."
|
||||
$connection = Connect-viserver $ESXIP -user $ESXUser -Password $ESXPWD -WarningAction SilentlyContinue
|
||||
|
||||
My-Logger "Enabling SSH Service for future troubleshooting ..."
|
||||
Start-VMHostService -HostService (Get-VMHost | Get-VMHostService | Where { $_.Key -eq "TSM-SSH"} ) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Configuring NTP server to $ntpserver and retarting service ..."
|
||||
Get-VMHost | Add-VMHostNtpServer $ntpserver | Out-File -Append -LiteralPath $verboseLogFile
|
||||
Get-VMHost | Get-VMHostFirewallException | where {$_.Name -eq "NTP client"} | Set-VMHostFirewallException -Enabled:$true | Out-File -Append -LiteralPath $verboseLogFile
|
||||
Get-VMHost | Get-VmHostService | Where-Object {$_.key -eq "ntpd"} | Start-VMHostService | Out-File -Append -LiteralPath $verboseLogFile
|
||||
Get-VMhost | Get-VmHostService | Where-Object {$_.key -eq "ntpd"} | Set-VMHostService -policy "automatic" | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
#Configure VSAN Bootstrap (http://www.virtuallyghetto.com/2013/09/how-to-bootstrap-vcenter-server-onto_9.html)
|
||||
My-Logger "Setting the VSAN Policy for ForceProvisiong ..."
|
||||
$esxcli = get-esxcli -V2
|
||||
$VSANPolicyDefaults = $esxcli.vsan.policy.setdefault.CreateArgs()
|
||||
$VSANPolicyDefaults.policy = $VSANPolicy
|
||||
$VSANPolicyDefaults.policyclass = "vdisk"
|
||||
$esxcli.vsan.policy.setdefault.Invoke($VSANPolicyDefaults) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
$VSANPolicyDefaults.policyclass = "vmnamespace"
|
||||
$esxcli.vsan.policy.setdefault.Invoke($VSANPolicyDefaults) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
# Create new VSAN Cluster
|
||||
My-Logger "Creating a new VSAN Cluster ..."
|
||||
$esxcli.vsan.cluster.new.Invoke() | Out-File -Append -LiteralPath $verboseLogFile
|
||||
$VSANDisks = $esxcli.storage.core.device.list.invoke() | Where {$_.isremovable -eq "false"} | Sort size
|
||||
"Found the following disks to use for VSAN:" | Out-File -Append -LiteralPath $verboseLogFile
|
||||
$VSANDisks | FT | Out-File -Append -LiteralPath $verboseLogFile
|
||||
$Performance = $VSANDisks[0]
|
||||
"Using $($Performance.Model) for Performance disk" | Out-File -Append -LiteralPath $verboseLogFile
|
||||
$Capacity = $VSANDisks[1]
|
||||
"Using $($Capacity.Model) for Capacity disk" | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Tagging $($Capacity.Model) as Capacity ..."
|
||||
$capacitytag = $esxcli.vsan.storage.tag.add.CreateArgs()
|
||||
$capacitytag.disk = $Capacity.Device
|
||||
$capacitytag.tag = "capacityFlash"
|
||||
$esxcli.vsan.storage.tag.add.Invoke($capacitytag) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Create VSAN Diskgroup to back VSAN Cluster ..."
|
||||
$addvsanstorage = $esxcli.vsan.storage.add.CreateArgs()
|
||||
$addvsanstorage.ssd = $Performance.Device
|
||||
$addvsanstorage.disks = $Capacity.device
|
||||
$esxcli.vsan.storage.add.Invoke($addvsanstorage) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Deploying VCSA using Script CLI + JSON ..."
|
||||
$config = (get-content –raw “$($VCSACDDrive)vcsa-cli-installer\templates\install\embedded_vCSA_on_ESXi.json” ) | convertfrom-json
|
||||
$config.'new.vcsa'.esxi.hostname = $ESXIP
|
||||
$config.'new.vcsa'.esxi.username = $ESXUser
|
||||
$config.'new.vcsa'.esxi.password = $ESXPWD
|
||||
$config.'new.vcsa'.esxi.datastore = "vsanDatastore"
|
||||
$config.'new.vcsa'.network.ip = $VCIP
|
||||
$config.'new.vcsa'.network.'dns.servers'[0] = $VCDNS
|
||||
$config.'new.vcsa'.network.gateway = $VCGW
|
||||
$config.'new.vcsa'.network.'system.name' = $VCIP #Change to $VCName if you have DNS setup
|
||||
$config.'new.vcsa'.network.prefix = $VCNetPrefix
|
||||
$config.'new.vcsa'.os.password = $VCPass
|
||||
$config.'new.vcsa'.appliance.'deployment.option' = $VCSADeploymentSize
|
||||
$config.'new.vcsa'.sso.password = $VCPass
|
||||
$config.'new.vcsa'.sso.'site-name' = $SSOSiteName
|
||||
$config.'new.vcsa'.sso.'domain-name' = $SSODomainName
|
||||
$config | convertto-json | set-content –path “$($ENV:Temp)\jsontemplate.json”
|
||||
invoke-expression “$($VCSACDDrive)vcsa-cli-installer\win32\vcsa-deploy.exe install --no-esx-ssl-verify --accept-eula --acknowledge-ceip $($ENV:Temp)\jsontemplate.json” | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Enable VSAN Traffic on VMKernel Network ..."
|
||||
$VMKernel = Get-VMHost $ESXIP | Get-VMHostNetworkAdapter -VMKernel | Where {$_.PortGroupName -eq $VMKNetforVSAN }
|
||||
$IsVSANEnabled = $VMKernel | Where { $_.VsanTrafficEnabled}
|
||||
If (-not $IsVSANEnabled) {
|
||||
My-Logger "Enabling VSAN Kernel on $VMKernel ..."
|
||||
$VMKernel | Set-VMHostNetworkAdapter -VsanTrafficEnabled $true -Confirm:$false | Out-File -Append -LiteralPath $verboseLogFile
|
||||
} Else {
|
||||
My-Logger "VSAN Kernel already enabled on $VmKernel ..."
|
||||
}
|
||||
|
||||
My-Logger "Disconnecting from ESXi Host: $ESXIP ..."
|
||||
Disconnect-VIServer $ESXIP -Force -Confirm:$false -WarningAction SilentlyContinue
|
||||
|
||||
My-Logger "Connecting to vCenter: $VCIP ..."
|
||||
$connection = Connect-VIServer -Server $VCIP -User $VCUser -Password $vcpass -WarningAction SilentlyContinue
|
||||
|
||||
My-Logger "Creating Datacenter: $datacenter ..."
|
||||
New-Datacenter -Name $datacenter -Location (Get-Folder -Type Datacenter) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
My-Logger "Creating Cluster: $cluster ..."
|
||||
New-Cluster -Name $cluster -Location (Get-Datacenter -Name $datacenter) -DrsEnabled -VsanEnabled | Out-File -Append -LiteralPath $verboseLogFile
|
||||
My-Logger "Adding ESXi Host $ESXIP to vCenter ..."
|
||||
Add-VMHost -Location (Get-Cluster -Name $cluster) -User $ESXUser -Password $ESXPWD -Name $ESXIP -Force | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Setting the VCSA NTP server to: $NTPServer ..."
|
||||
Connect-CISServer -Server $VCIP -User $VCUser -Password $VCPass
|
||||
(Get-CISService com.vmware.appliance.techpreview.ntp.server).set(@($NTPServer)) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Configuring Host syslog to VC ..."
|
||||
Get-VMHost | Set-VMHostSysLogServer -SysLogServer $VCIP | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Acknowledging Alarms on the cluster ..."
|
||||
$alarmMgr = Get-View AlarmManager
|
||||
Get-Cluster | where {$_.ExtensionData.TriggeredAlarmState} | %{
|
||||
$cluster = $_
|
||||
$Cluster.ExtensionData.TriggeredAlarmState | %{
|
||||
$alarmMgr.AcknowledgeAlarm($_.Alarm,$vm.ExtensionData.MoRef) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
}
|
||||
}
|
||||
|
||||
My-Logger "Creating @lamw Content Library with Nested ESXi Images ..."
|
||||
|
||||
# Get a Datastore to create the content library on
|
||||
$datastoreID = (Get-Datastore "vsanDatastore").extensiondata.moref.value
|
||||
|
||||
# Get the Service that works with Subscribed content libraries
|
||||
$ContentCatalog = Get-CisService com.vmware.content.subscribed_library
|
||||
|
||||
# Create a Subscribed content library on an existing datastore
|
||||
$createSpec = $ContentCatalog.help.create.create_spec.CreateExample()
|
||||
$createSpec.subscription_info.authentication_method = "NONE"
|
||||
$createSpec.subscription_info.ssl_thumbprint = "69:d9:9e:e9:0b:4b:68:24:09:2b:ce:14:d7:4a:f9:8c:bd:c6:5a:e9"
|
||||
$createSpec.subscription_info.automatic_sync_enabled = $true
|
||||
$createSpec.subscription_info.subscription_url = "https://s3-us-west-1.amazonaws.com/vghetto-content-library/lib.json"
|
||||
$createSpec.subscription_info.on_demand = $false
|
||||
$createSpec.subscription_info.password = $null
|
||||
$createSpec.server_guid = $null
|
||||
$createspec.name = "virtuallyGhetto CL"
|
||||
$createSpec.description = "@lamw CL: http://www.virtuallyghetto.com/2015/04/subscribe-to-vghetto-nested-esxi-template-content-library-in-vsphere-6-0.html"
|
||||
$createSpec.type = "SUBSCRIBED"
|
||||
$createSpec.publish_info = $null
|
||||
$datastoreID = [VMware.VimAutomation.Cis.Core.Types.V1.ID]$datastoreID
|
||||
$StorageSpec = New-Object PSObject -Property @{
|
||||
datastore_id = $datastoreID
|
||||
type = "DATASTORE"
|
||||
}
|
||||
$CreateSpec.storage_backings.Add($StorageSpec)
|
||||
$UniqueID = [guid]::NewGuid().tostring()
|
||||
$ContentCatalog.create($UniqueID, $createspec) | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Changing the default VSAN VM Storage Policy to FTT=0 & Force Provisioning to Yes ..."
|
||||
$VSANPolicy = Get-SpbmStoragePolicy "Virtual SAN Default Storage Policy"
|
||||
$Ruleset = New-SpbmRuleSet -Name “Rule-set 1” -AllOfRules @((New-SpbmRule -Capability VSAN.forceProvisioning $True), (New-SpbmRule -Capability VSAN.hostFailuresToTolerate 0))
|
||||
$VSANPolicy | Set-SpbmStoragePolicy -RuleSet $Ruleset | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Enabling VM Autostart for the VCSA VM ..."
|
||||
$VCVM = Get-VM
|
||||
$vmstartpolicy = Get-VMStartPolicy -VM $VCVM
|
||||
Set-VMHostStartPolicy (Get-VMHost $ESXIP | Get-VMHostStartPolicy) -Enabled:$true | Out-File -Append -LiteralPath $verboseLogFile
|
||||
Set-VMStartPolicy -StartPolicy $vmstartpolicy -StartAction PowerOn -StartDelay 0 | Out-File -Append -LiteralPath $verboseLogFile
|
||||
|
||||
My-Logger "Enabling SSH on VCSA for easier troubleshooting ..."
|
||||
$vcsassh = Get-CIsService com.vmware.appliance.access.ssh
|
||||
$vcsassh.set($true)
|
||||
|
||||
$EndTime = Get-Date
|
||||
$duration = [math]::Round((New-TimeSpan -Start $StartTime -End $EndTime).TotalMinutes,2)
|
||||
|
||||
My-Logger "================================"
|
||||
My-Logger "vSphere Lab Deployment Complete!"
|
||||
My-Logger "StartTime: $StartTime"
|
||||
My-Logger " EndTime: $EndTime"
|
||||
My-Logger " Duration: $duration minutes"
|
||||
Write-Host ""
|
||||
My-Logger "Access the vSphere Web Client at https://$VCIP/vsphere-client/"
|
||||
My-Logger "Access the HTML5 vSphere Web Client at https://$VCIP/ui/"
|
||||
My-Logger "Browse the vSphere REST APIs using the API Explorer here: https://$VCIP/apiexplorer/"
|
||||
My-Logger "================================"
|
||||
43
Scripts/New-ClusterHostGroup.ps1
Normal file
43
Scripts/New-ClusterHostGroup.ps1
Normal file
@@ -0,0 +1,43 @@
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Script name: New-ClusterHostGroup.ps1
|
||||
Created on: 2016-10-25
|
||||
Author: Peter D. Jorgensen (@pjorg, pjorg.com)
|
||||
Dependencies: None known
|
||||
===Tested Against Environment====
|
||||
vSphere Version: 5.5, 6.0
|
||||
PowerCLI Version: PowerCLI 6.5R1
|
||||
PowerShell Version: 5.0
|
||||
OS Version: Windows 10, Windows 7
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Creates a DRS Host Group in a vSphere cluster.
|
||||
.Example
|
||||
$ProdCluster = Get-Cluster *prod*
|
||||
$OddHosts = $ProdCluster | Get-VMHost | ?{ $_.Name -match 'esxi-\d*[13579]+.\lab\.local' }
|
||||
.\New-ClusterHostGroup.ps1 -Name 'OddProdHosts' -Cluster $ProdCluster -VMHost $OddHosts
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$True,Position=1)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$True,ValueFromPipeline=$True,Position=2)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster]$Cluster,
|
||||
[Parameter(Mandatory=$False,Position=3)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VMHost[]]$VMHost
|
||||
)
|
||||
|
||||
$NewGroup = New-Object VMware.Vim.ClusterHostGroup -Property @{
|
||||
'Name'=$Name
|
||||
'Host'=$VMHost.Id
|
||||
}
|
||||
|
||||
$spec = New-Object VMware.Vim.ClusterConfigSpecEx -Property @{
|
||||
'GroupSpec'=(New-Object VMware.Vim.ClusterGroupSpec -Property @{
|
||||
'Info'=$NewGroup
|
||||
})
|
||||
}
|
||||
|
||||
$ClusterToReconfig = Get-View -VIObject $Cluster -Property Name
|
||||
$ClusterToReconfig.ReconfigureComputeResource($spec, $true)
|
||||
43
Scripts/New-ClusterVmGroup.ps1
Normal file
43
Scripts/New-ClusterVmGroup.ps1
Normal file
@@ -0,0 +1,43 @@
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Script name: New-ClusterVmGroup.ps1
|
||||
Created on: 2016-10-25
|
||||
Author: Peter D. Jorgensen (@pjorg, pjorg.com)
|
||||
Dependencies: None known
|
||||
===Tested Against Environment====
|
||||
vSphere Version: 5.5, 6.0
|
||||
PowerCLI Version: PowerCLI 6.5R1
|
||||
PowerShell Version: 5.0
|
||||
OS Version: Windows 10, Windows 7
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Creates a DRS VM Group in a vSphere cluster.
|
||||
.Example
|
||||
$ProdCluster = Get-Cluster *prod*
|
||||
$EvenVMs = $ProdCluster | Get-VM | ?{ $_.Name -match 'MyVM-\d*[02468]+' }
|
||||
.\New-ClusterVmGroup.ps1 -Name 'EvenVMs' -Cluster $ProdCluster -VM $EvenVMs
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$True,Position=1)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$True,ValueFromPipeline=$True,Position=2)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster]$Cluster,
|
||||
[Parameter(Mandatory=$False,Position=3)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.VirtualMachine[]]$VM
|
||||
)
|
||||
|
||||
$NewGroup = New-Object VMware.Vim.ClusterVmGroup -Property @{
|
||||
'Name'=$Name
|
||||
'VM'=$VM.Id
|
||||
}
|
||||
|
||||
$spec = New-Object VMware.Vim.ClusterConfigSpecEx -Property @{
|
||||
'GroupSpec'=(New-Object VMware.Vim.ClusterGroupSpec -Property @{
|
||||
'Info'=$NewGroup
|
||||
})
|
||||
}
|
||||
|
||||
$ClusterToReconfig = Get-View -VIObject $Cluster -Property Name
|
||||
$ClusterToReconfig.ReconfigureComputeResource($spec, $true)
|
||||
48
Scripts/New-ClusterVmHostRule.ps1
Normal file
48
Scripts/New-ClusterVmHostRule.ps1
Normal file
@@ -0,0 +1,48 @@
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Script name: New-ClusterVmHostRule.ps1
|
||||
Created on: 2016-10-25
|
||||
Author: Peter D. Jorgensen (@pjorg, pjorg.com)
|
||||
Dependencies: None known
|
||||
===Tested Against Environment====
|
||||
vSphere Version: 5.5, 6.0
|
||||
PowerCLI Version: PowerCLI 6.5R1
|
||||
PowerShell Version: 5.0
|
||||
OS Version: Windows 10, Windows 7
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Creates a VM to Host affinity rule in a vSphere cluster.
|
||||
.Example
|
||||
$ProdCluster = Get-Cluster *prod*
|
||||
.\New-ClusterVmHostRule.ps1 -Name 'Even VMs to Odd Hosts' -AffineHostGroupName 'OddHosts' -VMGroupName 'EvenVMs' -Enabled:$true -Cluster $ProdCluster
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(Mandatory=$True,Position=1)]
|
||||
[String]$Name,
|
||||
[Parameter(Mandatory=$True,Position=2)]
|
||||
[String]$AffineHostGroupName,
|
||||
[Parameter(Mandatory=$True,Position=3)]
|
||||
[String]$VMGroupName,
|
||||
[Parameter(Mandatory=$False,Position=4)]
|
||||
[Switch]$Enabled=$True,
|
||||
[Parameter(Mandatory=$True,ValueFromPipeline=$True,Position=5)]
|
||||
[VMware.VimAutomation.ViCore.Types.V1.Inventory.Cluster]$Cluster
|
||||
)
|
||||
|
||||
$NewRule = New-Object VMware.Vim.ClusterVmHostRuleInfo -Property @{
|
||||
'AffineHostGroupName'=$AffineHostGroupName
|
||||
'VmGroupName'=$VMGroupName
|
||||
'Enabled'=$Enabled
|
||||
'Name'=$Name
|
||||
}
|
||||
|
||||
$spec = New-Object VMware.Vim.ClusterConfigSpecEx -Property @{
|
||||
'RulesSpec'=(New-Object VMware.Vim.ClusterRuleSpec -Property @{
|
||||
'Info'=$NewRule
|
||||
})
|
||||
}
|
||||
|
||||
$ClusterToReconfig = Get-View -VIObject $Cluster -Property Name
|
||||
$ClusterToReconfig.ReconfigureComputeResource($spec, $true)
|
||||
31
Scripts/Start-VMHostSsh.ps1
Normal file
31
Scripts/Start-VMHostSsh.ps1
Normal file
@@ -0,0 +1,31 @@
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Script name: Start-VMHostSsh.ps1
|
||||
Created on: 2016-07-01
|
||||
Author: Peter D. Jorgensen (@pjorg, pjorg.com)
|
||||
Dependencies: None known
|
||||
===Tested Against Environment====
|
||||
vSphere Version: 5.5, 6.0
|
||||
PowerCLI Version: PowerCLI 6.5R1
|
||||
PowerShell Version: 5.0
|
||||
OS Version: Windows 10, Windows 7
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Starts the TSM-SSH service on VMHosts.
|
||||
.Example
|
||||
.\Start-VMHostSsh -VMHost (Get-VMHost -Name 'esxi-001.lab.local')
|
||||
.Example
|
||||
$OddHosts = Get-VMHost | ?{ $_.Name -match 'esxi-\d*[13579]+.\lab\.local' }
|
||||
.\Start-VMHost -VMHost $OddHosts
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(ValueFromPipeline=$True,Mandatory=$True,Position=0)]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMHost
|
||||
)
|
||||
|
||||
Process {
|
||||
$svcSys = Get-View $VMHost.ExtensionData.ConfigManager.ServiceSystem
|
||||
$svcSys.StartService('TSM-SSH')
|
||||
}
|
||||
31
Scripts/Stop-VMHostSsh.ps1
Normal file
31
Scripts/Stop-VMHostSsh.ps1
Normal file
@@ -0,0 +1,31 @@
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Script name: Stop-VMHostSsh.ps1
|
||||
Created on: 2016-07-01
|
||||
Author: Peter D. Jorgensen (@pjorg, pjorg.com)
|
||||
Dependencies: None known
|
||||
===Tested Against Environment====
|
||||
vSphere Version: 5.5, 6.0
|
||||
PowerCLI Version: PowerCLI 6.5R1
|
||||
PowerShell Version: 5.0
|
||||
OS Version: Windows 10, Windows 7
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Stops the TSM-SSH service on VMHosts.
|
||||
.Example
|
||||
.\Stop-VMHostSsh -VMHost (Get-VMHost -Name 'esxi-001.lab.local')
|
||||
.Example
|
||||
$EvenHosts = Get-VMHost | ?{ $_.Name -match 'esxi-\d*[02468]+.\lab\.local' }
|
||||
.\Stop-VMHost -VMHost $EvenHosts
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
Param(
|
||||
[Parameter(ValueFromPipeline=$True,Mandatory=$True,Position=0)]
|
||||
[VMware.VimAutomation.ViCore.Impl.V1.Inventory.VMHostImpl[]]$VMHost
|
||||
)
|
||||
|
||||
Process {
|
||||
$svcSys = Get-View $VMHost.ExtensionData.ConfigManager.ServiceSystem
|
||||
$svcSys.StopService('TSM-SSH')
|
||||
}
|
||||
4215
Scripts/vTool_2016aug.ps1
Normal file
4215
Scripts/vTool_2016aug.ps1
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user