Added folders for all .psm1 Files in /Modules
Signed-off-by: Kevin Kirkpatrick <kevin@vmotioned.com>
This commit is contained in:
202
Modules/Backup-VCSA/Backup-VCSA.psm1
Normal file
202
Modules/Backup-VCSA/Backup-VCSA.psm1
Normal file
@@ -0,0 +1,202 @@
|
||||
Function Backup-VCSAToFile {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Date: October 30, 2016
|
||||
Organization: VMware
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
This function will allow you to create a full or partial backup of your
|
||||
VCSA appliance. (vSphere 6.5 and higher)
|
||||
|
||||
.DESCRIPTION
|
||||
Use this function to backup your VCSA to a remote location
|
||||
|
||||
.EXAMPLE
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword = "VMw@re123"
|
||||
$Comment = "First API Backup"
|
||||
$LocationType = "FTP"
|
||||
$location = "10.144.99.5/vcsabackup-$((Get-Date).ToString('yyyy-MM-dd-hh-mm'))"
|
||||
$LocationUser = "admin"
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$locationPassword = "VMw@re123"
|
||||
PS C:\> Backup-VCSAToFile -BackupPassword $BackupPassword -LocationType $LocationType -Location $location -LocationUser $LocationUser -LocationPassword $locationPassword -Comment "This is a demo" -ShowProgress -FullBackup
|
||||
|
||||
|
||||
.NOTES
|
||||
Credit goes to @AlanRenouf for sharing the base of this function with me which I was able to take and make more robust as well as add in progress indicators
|
||||
You must be connected to the CisService for this to work, if you are not connected, the function will prompt you for your credentials
|
||||
If a -LocationType is not chosen, the function will default to FTP.
|
||||
The destination location for a backup must be an empty folder (easiest to use the get-date cmdlet in the location)
|
||||
-ShowProgress will give you a progressbar as well as updates in the console
|
||||
-SeatBackup will only backup the config whereas -Fullbackup grabs the historical data as well
|
||||
#>
|
||||
param (
|
||||
[Parameter(ParameterSetName=’FullBackup’)]
|
||||
[switch]$FullBackup,
|
||||
[Parameter(ParameterSetName=’SeatBackup’)]
|
||||
[switch]$SeatBackup,
|
||||
[ValidateSet('FTPS', 'HTTP', 'SCP', 'HTTPS', 'FTP')]
|
||||
$LocationType = "FTP",
|
||||
$Location,
|
||||
$LocationUser,
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$LocationPassword,
|
||||
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword,
|
||||
$Comment = "Backup job",
|
||||
[switch]$ShowProgress
|
||||
)
|
||||
Begin {
|
||||
if (!($global:DefaultCisServers)){
|
||||
[System.Windows.Forms.MessageBox]::Show("It appears you have not created a connection to the CisServer. You will now be prompted to enter your vCenter credentials to continue" , "Connect to CisServer") | out-null
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
} else {
|
||||
$Connection = $global:DefaultCisServers
|
||||
}
|
||||
if ($FullBackup) {$parts = @("common","seat")}
|
||||
if ($SeatBackup) {$parts = @("seat")}
|
||||
}
|
||||
Process{
|
||||
$BackupAPI = Get-CisService com.vmware.appliance.recovery.backup.job
|
||||
$CreateSpec = $BackupAPI.Help.create.piece.CreateExample()
|
||||
$CreateSpec.parts = $parts
|
||||
$CreateSpec.backup_password = $BackupPassword
|
||||
$CreateSpec.location_type = $LocationType
|
||||
$CreateSpec.location = $Location
|
||||
$CreateSpec.location_user = $LocationUser
|
||||
$CreateSpec.location_password = $LocationPassword
|
||||
$CreateSpec.comment = $Comment
|
||||
try {
|
||||
$BackupJob = $BackupAPI.create($CreateSpec)
|
||||
}
|
||||
catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
|
||||
|
||||
If ($ShowProgress){
|
||||
do {
|
||||
$BackupAPI.get("$($BackupJob.ID)") | select id, progress, state
|
||||
$progress = ($BackupAPI.get("$($BackupJob.ID)").progress)
|
||||
Write-Progress -Activity "Backing up VCSA" -Status $BackupAPI.get("$($BackupJob.ID)").state -PercentComplete ($BackupAPI.get("$($BackupJob.ID)").progress) -CurrentOperation "$progress% Complete"
|
||||
start-sleep -seconds 5
|
||||
} until ($BackupAPI.get("$($BackupJob.ID)").progress -eq 100 -or $BackupAPI.get("$($BackupJob.ID)").state -ne "INPROGRESS")
|
||||
|
||||
$BackupAPI.get("$($BackupJob.ID)") | select id, progress, state
|
||||
}
|
||||
Else {
|
||||
$BackupJob | select id, progress, state
|
||||
}
|
||||
}
|
||||
End {}
|
||||
}
|
||||
|
||||
Function Get-VCSABackupJobs {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Date: October 30, 2016
|
||||
Organization: VMware
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Get-VCSABackupJobs returns a list of all backup jobs VCSA has ever performed (vSphere 6.5 and higher)
|
||||
|
||||
.DESCRIPTION
|
||||
Get-VCSABackupJobs returns a list of all backup jobs VCSA has ever performed
|
||||
|
||||
.EXAMPLE
|
||||
PS C:\> Get-VCSABackupJobs
|
||||
|
||||
.NOTES
|
||||
The values returned are read as follows:
|
||||
YYYYMMDD-hhmmss-vcsabuildnumber
|
||||
You can pipe the results of this function into the Get-VCSABackupStatus function
|
||||
Get-VCSABackupJobs | select -First 1 | Get-VCSABackupStatus <- Most recent backup
|
||||
#>
|
||||
param (
|
||||
[switch]$ShowNewest
|
||||
)
|
||||
Begin {
|
||||
if (!($global:DefaultCisServers)){
|
||||
[System.Windows.Forms.MessageBox]::Show("It appears you have not created a connection to the CisServer. You will now be prompted to enter your vCenter credentials to continue" , "Connect to CisServer") | out-null
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
} else {
|
||||
$Connection = $global:DefaultCisServers
|
||||
}
|
||||
}
|
||||
Process{
|
||||
|
||||
$BackupAPI = Get-CisService com.vmware.appliance.recovery.backup.job
|
||||
|
||||
try {
|
||||
if ($ShowNewest) {
|
||||
$results = $BackupAPI.list()
|
||||
$results[0]
|
||||
} else {
|
||||
$BackupAPI.list()
|
||||
}
|
||||
}
|
||||
catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
End {}
|
||||
}
|
||||
|
||||
Function Get-VCSABackupStatus {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Brian Graf
|
||||
Date: October 30, 2016
|
||||
Organization: VMware
|
||||
Blog: www.vtagion.com
|
||||
Twitter: @vBrianGraf
|
||||
===========================================================================
|
||||
|
||||
.SYNOPSIS
|
||||
Returns the ID, Progress, and State of a VCSA backup (vSphere 6.5 and higher)
|
||||
|
||||
.DESCRIPTION
|
||||
Returns the ID, Progress, and State of a VCSA backup
|
||||
|
||||
.EXAMPLE
|
||||
PS C:\> $backups = Get-VCSABackupJobs
|
||||
$backups[0] | Get-VCSABackupStatus
|
||||
|
||||
.NOTES
|
||||
The BackupID can be piped in from the Get-VCSABackupJobs function and can return multiple job statuses
|
||||
#>
|
||||
Param (
|
||||
[parameter(ValueFromPipeline=$True)]
|
||||
[string[]]$BackupID
|
||||
)
|
||||
Begin {
|
||||
if (!($global:DefaultCisServers)){
|
||||
[System.Windows.Forms.MessageBox]::Show("It appears you have not created a connection to the CisServer. You will now be prompted to enter your vCenter credentials to continue" , "Connect to CisServer") | out-null
|
||||
$Connection = Connect-CisServer $global:DefaultVIServer
|
||||
} else {
|
||||
$Connection = $global:DefaultCisServers
|
||||
}
|
||||
|
||||
$BackupAPI = Get-CisService com.vmware.appliance.recovery.backup.job
|
||||
}
|
||||
Process{
|
||||
|
||||
foreach ($id in $BackupID) {
|
||||
$BackupAPI.get("$id") | select id, progress, state
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
End {}
|
||||
}
|
||||
93
Modules/Get-NICDetails/Get-NICDetails.psm1
Normal file
93
Modules/Get-NICDetails/Get-NICDetails.psm1
Normal file
@@ -0,0 +1,93 @@
|
||||
function Get-NICDetails {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2017.02 ver 1.0 Base Release
|
||||
===========================================================================
|
||||
External Code Sources:
|
||||
-
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vSphere Version: ESXi 6.0 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 2008 R2, Server 2012 R2
|
||||
Keyword: ESXi, NIC, vmnic, Driver, Firmware
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
Reports Firmware and Driver Details for your ESXi vmnics.
|
||||
|
||||
.Example
|
||||
Get-NICDetails -Clustername *
|
||||
|
||||
.PARAMETER Clustername
|
||||
Name or Wildcard of your vSphere Cluster Name to process.
|
||||
|
||||
|
||||
#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)]
|
||||
[ValidateNotNullorEmpty()]
|
||||
[String] $Clustername
|
||||
|
||||
)
|
||||
|
||||
Begin {
|
||||
$Validate = $True
|
||||
|
||||
if (($myCluster = Get-Cluster -Name $Clustername).count -lt 1) {
|
||||
$Validate = $False
|
||||
thow "No Cluster '$myCluster' found!"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Process {
|
||||
|
||||
$MyView = @()
|
||||
if ($Validate -eq $True) {
|
||||
|
||||
foreach ($myVMhost in ($myCluster | Get-VMHost)) {
|
||||
|
||||
$esxcli2 = Get-ESXCLI -VMHost $myVMhost -V2
|
||||
$niclist = $esxcli2.network.nic.list.invoke()
|
||||
|
||||
$nicdetails = @()
|
||||
foreach ($nic in $niclist) {
|
||||
|
||||
$args = $esxcli2.network.nic.get.createargs()
|
||||
$args.nicname = $nic.name
|
||||
$nicdetail = $esxcli2.network.nic.get.Invoke($args)
|
||||
$nicdetails += $nicdetail
|
||||
|
||||
}
|
||||
ForEach ($nicdetail in $nicdetails){
|
||||
$NICReport = [PSCustomObject] @{
|
||||
Host = $myVMhost.Name
|
||||
vmnic = $nicdetail.Name
|
||||
LinkStatus = $nicdetail.LinkStatus
|
||||
BusInfo = $nicdetail.driverinfo.BusInfo
|
||||
Driver = $nicdetail.driverinfo.Driver
|
||||
FirmwareVersion = $nicdetail.driverinfo.FirmwareVersion
|
||||
DriverVersion = $nicdetail.driverinfo.Version
|
||||
}
|
||||
$MyView += $NICReport
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
$MyView
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
131
Modules/Get-NewAndRemovedVMs/Get-NewAndRemovedVMs.psm1
Normal file
131
Modules/Get-NewAndRemovedVMs/Get-NewAndRemovedVMs.psm1
Normal file
@@ -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}
|
||||
}
|
||||
}
|
||||
114
Modules/Get-VMmaxIOPS/Get-VMmaxIOPS.psm1
Normal file
114
Modules/Get-VMmaxIOPS/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
|
||||
}
|
||||
|
||||
}
|
||||
234
Modules/Konfig-ESXi/Konfig-ESXi.psm1
Normal file
234
Modules/Konfig-ESXi/Konfig-ESXi.psm1
Normal file
@@ -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
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
123
Modules/PSvLIMessage/PSvLIMessage.psm1
Normal file
123
Modules/PSvLIMessage/PSvLIMessage.psm1
Normal file
@@ -0,0 +1,123 @@
|
||||
add-type @"
|
||||
using System.Net;
|
||||
using System.Security.Cryptography.X509Certificates;
|
||||
public class TrustAllCertsPolicy : ICertificatePolicy {
|
||||
public bool CheckValidationResult(
|
||||
ServicePoint srvPoint, X509Certificate certificate,
|
||||
WebRequest request, int certificateProblem) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
"@
|
||||
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
|
||||
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Organization: Private
|
||||
Personal Blog: mycloudrevolution.com
|
||||
Twitter: @vMarkus_K
|
||||
===========================================================================
|
||||
Tested Against Environment:
|
||||
vRealize Log Insight 3.3.1
|
||||
PowerShell Version: 4.0, 5.0
|
||||
OS Version: Windows 8.1, Server 2012 R2
|
||||
Keyword: vRealize, RestAPI
|
||||
|
||||
Dependencies:
|
||||
PowerCLI Version: PowerCLI 6.3 R1
|
||||
|
||||
.SYNOPSIS
|
||||
Push Messages to VMware vRealize Log Insight.
|
||||
|
||||
.DESCRIPTION
|
||||
Creates a Messages in VMware vRealize Log Insight via the Ingestion API
|
||||
|
||||
.EXAMPLE
|
||||
Push-vLIMessage -vLIServer "loginsight.lan.local" -vLIAgentID "12862842-5A6D-679C-0E38-0E2BE888BB28" -Text "My Test"
|
||||
|
||||
.EXAMPLE
|
||||
Push-vLIMessage -vLIServer "loginsight.lan.local" -vLIAgentID "12862842-5A6D-679C-0E38-0E2BE888BB28" -Text "My Test" -Hostname MyTEST -FieldName myTest -FieldContent myTest
|
||||
|
||||
.PARAMETER vLIServer
|
||||
Specify the FQDN of your vRealize Log Insight Appliance
|
||||
|
||||
.PARAMETER vLIAgentID
|
||||
Specify the vRealize Log Insight Agent ID, e.g. "12862842-5A6D-679C-0E38-0E2BE888BB28"
|
||||
|
||||
.PARAMETER Text
|
||||
Specify the Event Text
|
||||
|
||||
.PARAMETER Hostname
|
||||
Specify the Hostanme displayed in vRealize Log Insight
|
||||
|
||||
.PARAMETER FieldName
|
||||
Specify the a Optional Field Name for vRealize Log Insight
|
||||
|
||||
.PARAMETER FieldContent
|
||||
Specify the a Optional FieldContent for the Field in -FieldName for vRealize Log Insight
|
||||
If FielName is missing and FieldContent is given, it will be ignored
|
||||
|
||||
#Requires PS -Version 3.0
|
||||
|
||||
#>
|
||||
function Push-vLIMessage {
|
||||
|
||||
[cmdletbinding()]
|
||||
param (
|
||||
[parameter(Mandatory=$true)]
|
||||
[string]$Text,
|
||||
[parameter(Mandatory=$true)]
|
||||
[string]$vLIServer,
|
||||
[parameter(Mandatory=$true)]
|
||||
[string]$vLIAgentID,
|
||||
[parameter(Mandatory=$false)]
|
||||
[string]$Hostname = $env:computername,
|
||||
[parameter(Mandatory=$false)]
|
||||
[string]$FieldName,
|
||||
[parameter(Mandatory=$false)]
|
||||
[string]$FieldContent = ""
|
||||
)
|
||||
Process {
|
||||
$Field_vLI = [ordered]@{
|
||||
name = "PS_vLIMessage"
|
||||
content = "true"
|
||||
}
|
||||
$Field_HostName = [ordered]@{
|
||||
name = "hostname"
|
||||
content = $Hostname
|
||||
}
|
||||
|
||||
$Fields = @($Field_vLI, $Field_HostName)
|
||||
|
||||
if ($FieldName) {
|
||||
$Field_Custom = [ordered]@{
|
||||
name = $FieldName
|
||||
content = $FieldContent
|
||||
}
|
||||
$Fields += @($Field_Custom)
|
||||
}
|
||||
|
||||
$Restcall = @{
|
||||
messages = ([Object[]]([ordered]@{
|
||||
text = ($Text)
|
||||
fields = ([Object[]]$Fields)
|
||||
}))
|
||||
} | convertto-json -Depth 4
|
||||
|
||||
$Resturl = ("http://" + $vLIServer + ":9000/api/v1/messages/ingest/" + $vLIAgentID)
|
||||
try
|
||||
{
|
||||
$Response = Invoke-RestMethod $Resturl -Method Post -Body $Restcall -ContentType 'application/json' -ErrorAction stop
|
||||
Write-Information "REST Call to Log Insight server successful"
|
||||
Write-Verbose $Response
|
||||
}
|
||||
catch
|
||||
{
|
||||
Write-Error "REST Call failed to Log Insight server"
|
||||
Write-Verbose $error[0]
|
||||
Write-Verbose $Resturl
|
||||
}
|
||||
}
|
||||
}
|
||||
468
Modules/ProactiveHA/ProactiveHA.psm1
Normal file
468
Modules/ProactiveHA/ProactiveHA.psm1
Normal file
@@ -0,0 +1,468 @@
|
||||
Function New-PHAProvider {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to register a new Proactive HA Provider with vCenter Server
|
||||
.PARAMETER ProviderName
|
||||
Name of ProactiveHA Provider
|
||||
.PARAMETER ComponentType
|
||||
Name of a supported ComponentType that ProactiveHA supports (Fan, Memory, Network, Power or Storage)
|
||||
.PARAMETER ComponentDescription
|
||||
Description of the health check for the given component
|
||||
.PARAMETER ComponentId
|
||||
Unique identifier for the given component within a ProactiveHA Provider
|
||||
.EXAMPLE
|
||||
New-PHAProvider -ProviderName "virtuallyGhetto" -ComponentType Power -ComponentDescription "Simulated ProactiveHA Provider" -ComponentId "Power"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderName,
|
||||
[Parameter(Mandatory=$true)][ValidateSet("Fan","Memory","Network","Power","Storage")][String]$ComponentType,
|
||||
[Parameter(Mandatory=$true)][String]$ComponentDescription,
|
||||
[Parameter(Mandatory=$true)][String]$ComponentId
|
||||
)
|
||||
Write-Host -ForegroundColor Red "`n******************** DISCLAIMER ********************"
|
||||
Write-Host -ForegroundColor Red "**** THIS IS NOT INTENDED FOR PRODUCTION USE ****"
|
||||
Write-Host -ForegroundColor Red "**** LEARNING PURPOSES ONLY ****"
|
||||
Write-Host -ForegroundColor Red "******************** DISCLAIMER ********************`n"
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$healthInfo = [VMware.Vim.HealthUpdateInfo] @{
|
||||
ComponentType = $ComponentType
|
||||
description = $ComponentDescription
|
||||
Id = $ComponentId
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Host "`nRegistering new Proactive HA Provider $ProviderName ..."
|
||||
$providerId = $healthManager.RegisterHealthUpdateProvider($ProviderName,$healthInfo)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-PHAProvider {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to return list of all Proactive HA Providers registered with vCenter Server
|
||||
.EXAMPLE
|
||||
Get-PHAProvider
|
||||
#>
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$healthProviderResults = @()
|
||||
$hpIDs = $healthManager.QueryProviderList()
|
||||
|
||||
foreach ($hpID in $hpIDs) {
|
||||
$hpName = $healthManager.QueryProviderName($hpID)
|
||||
$hpConfig = $healthManager.QueryHealthUpdateInfos($hpID)
|
||||
|
||||
$hp = [pscustomobject] @{
|
||||
ProviderName = $hpName
|
||||
ProviderID = $hpID
|
||||
ComponentType = $hpConfig.componentType
|
||||
ComponentID = $hpConfig.id
|
||||
Description = $hpConfig.description
|
||||
}
|
||||
$healthProviderResults+=$hp
|
||||
}
|
||||
$healthProviderResults
|
||||
}
|
||||
|
||||
Function Remove-PHAProvider {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to remove a registered Proactive HA Provider from vCenter Server
|
||||
.PARAMETER ProviderId
|
||||
The ProactiveHA provider ID (retrieved from Get-PHAProvider) to unregister
|
||||
.EXAMPLE
|
||||
Remove-PHAProvider -ProviderID "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderId
|
||||
)
|
||||
|
||||
Write-Host -ForegroundColor Red "`n******************** DISCLAIMER ********************"
|
||||
Write-Host -ForegroundColor Red "**** THIS IS NOT INTENDED FOR PRODUCTION USE ****"
|
||||
Write-Host -ForegroundColor Red "**** LEARNING PURPOSES ONLY ****"
|
||||
Write-Host -ForegroundColor Red "******************** DISCLAIMER ********************`n"
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
try {
|
||||
Write-Host "`nUnregistering Proactive HA Provider $ProviderId ... "
|
||||
$healthManager.UnregisterHealthUpdateProvider($providerId)
|
||||
} catch {
|
||||
if($Error[0].Exception.InnerException.MethodFault.getType().Name -eq "InvalidState") {
|
||||
Write-host -ForegroundColor Red "The Proactive HA Provider is still in use, please disable it before unregistering"
|
||||
} else {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Set-PHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to enable/disable Proactive HA for vSphere Cluster
|
||||
.PARAMETER Cluster
|
||||
Name of the vSphere Cluster to enable Proactive HA
|
||||
.PARAMETER ProviderId
|
||||
Proactive HA Provider ID to enable in vSphere Cluster
|
||||
.PARAMETER ClusterMode
|
||||
Whether Proactive HA should be "Automated" or "Manual" for actions it will take
|
||||
.PARAMETER ModerateRemediation
|
||||
Type of operation (Maintenance Mode or Quaratine Mode) to perform when a Moderate issue is observed
|
||||
.PARAMETER SevereRemediation
|
||||
Type of operation (Maintenance Mode or Quaratine Mode) to perform when a Severe issue is observed
|
||||
.EXAMPLE
|
||||
Set-PHAConfig -Cluster VSAN-Cluster -Enabled -ClusterMode Automated -ModerateRemediation QuarantineMode -SevereRemediation QuarantineMode -ProviderID "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
.EXAMPLE
|
||||
Set-PHAConfig -Cluster VSAN-Cluster -Disabled -ProviderID "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderId,
|
||||
[Parameter(Mandatory=$true)][String]$Cluster,
|
||||
[Parameter(Mandatory=$false)][ValidateSet("Automated","Manual")]$ClusterMode="Manual",
|
||||
[Parameter(Mandatory=$false)][ValidateSet("MaintenanceMode","QuarantineMode")]$ModerateRemediation="QuarantineMode",
|
||||
[Parameter(Mandatory=$false)][ValidateSet("MaintenanceMode","QuarantineMode")]$SevereRemediation="QuarantineMode",
|
||||
[Switch]$Enabled,
|
||||
[Switch]$Disabled
|
||||
)
|
||||
|
||||
$ClusterView = Get-View -ViewType ClusterComputeResource -Property Name,Host,ConfigurationEx -Filter @{"Name" = $Cluster}
|
||||
|
||||
if($ClusterView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster $cluster ..."
|
||||
break
|
||||
}
|
||||
|
||||
$vmhosts = $ClusterView.host
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
if($Enabled) {
|
||||
try {
|
||||
$entities = @()
|
||||
foreach ($vmhost in $vmhosts) {
|
||||
if(-not $healthManager.HasMonitoredEntity($ProviderId,$vmhost)) {
|
||||
$entities += $vmhost
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Enabling Proactive HA monitoring for all ESXi hosts in cluster ..."
|
||||
$healthManager.AddMonitoredEntities($ProviderId,$entities)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
|
||||
try {
|
||||
$healthProviders = @()
|
||||
|
||||
# Make sure not to remove existing ProactiveHA providers
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$currentHPs = $ClusterView.ConfigurationEx.infraUpdateHaConfig.providers
|
||||
foreach ($currentHP in $currentHPs) {
|
||||
$healthProviders+=$currentHP
|
||||
}
|
||||
if(-not ($healthProviders -contains $ProviderID)) {
|
||||
$healthProviders+=$ProviderId
|
||||
}
|
||||
} else {
|
||||
$healthProviders+=$ProviderId
|
||||
}
|
||||
|
||||
$PHASpec = [VMware.Vim.ClusterInfraUpdateHaConfigInfo] @{
|
||||
enabled = $true
|
||||
behavior = $ClusterMode
|
||||
moderateRemediation = $ModerateRemediation
|
||||
severeRemediation = $SevereRemediation
|
||||
providers = $healthProviders
|
||||
}
|
||||
|
||||
$spec = [VMware.Vim.ClusterConfigSpecEx] @{
|
||||
infraUpdateHaConfig = $PHASpec
|
||||
}
|
||||
|
||||
Write-Host "Enabling Proactive HA Provider $ProviderId on $Cluster ..."
|
||||
$task = $ClusterView.ReconfigureComputeResource_Task($spec,$True)
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task | Out-Null
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
|
||||
if($Disabled) {
|
||||
foreach ($vmhost in $vmhosts) {
|
||||
if($vmhost.runtime.inQuarantineMode) {
|
||||
Write-Host -ForegroundColor Red $vmhost.name " is currently still in Quaratine Mode, please remediate this before disabling Proactive HA"
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
$healthProviders = @()
|
||||
|
||||
# Make sure not to remove existing ProactiveHA providers
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$currentHPs = $ClusterView.ConfigurationEx.infraUpdateHaConfig.providers
|
||||
foreach ($currentHP in $currentHPs) {
|
||||
if($currentHP -ne $ProviderId) {
|
||||
$healthProviders+=$currentHP
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$PHASpec = [VMware.Vim.ClusterInfraUpdateHaConfigInfo] @{
|
||||
enabled = $true
|
||||
behavior = $ClusterMode
|
||||
moderateRemediation = $ModerateRemediation
|
||||
severeRemediation = $SevereRemediation
|
||||
providers = $healthProviders
|
||||
}
|
||||
|
||||
$spec = [VMware.Vim.ClusterConfigSpecEx] @{
|
||||
infraUpdateHaConfig = $PHASpec
|
||||
}
|
||||
|
||||
Write-Host "Disabling Proactive HA Provider $ProviderId on $Cluster ..."
|
||||
$task = $ClusterView.ReconfigureComputeResource_Task($spec,$True)
|
||||
$task1 = Get-Task -Id ("Task-$($task.value)")
|
||||
$task1 | Wait-Task | Out-Null
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
|
||||
$ClusterView.UpdateViewData()
|
||||
|
||||
try {
|
||||
$entities = @()
|
||||
foreach ($vmhost in $vmhosts) {
|
||||
if($healthManager.HasMonitoredEntity($ProviderId,$vmhost)) {
|
||||
$entities += $vmhost
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "Disabling Proactive HA monitoring for all ESXi hosts in cluster ..."
|
||||
$healthManager.RemoveMonitoredEntities($ProviderId,$entities)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-PHAConfig {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to retrieve Proactive HA configuration for a vSphere Cluster
|
||||
.PARAMETER Cluster
|
||||
Name of the vSphere Cluster to check Proactive HA configuration
|
||||
.EXAMPLE
|
||||
Get-PHAConfig -Cluster VSAN-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
|
||||
$ClusterView = Get-View -ViewType ClusterComputeResource -Property Name,ConfigurationEx -Filter @{"Name" = $Cluster}
|
||||
|
||||
if($ClusterView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster $cluster ..."
|
||||
break
|
||||
}
|
||||
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$phSettings = $ClusterView.ConfigurationEx.InfraUpdateHaConfig
|
||||
$providers = $ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers
|
||||
$healthProviders = @()
|
||||
foreach ($provider in $providers) {
|
||||
$providerName = $healthManager.QueryProviderName($provider)
|
||||
$healthProviders+=$providerName
|
||||
}
|
||||
|
||||
$pHAConfig = [pscustomobject] @{
|
||||
Enabled = $phSettings.Enabled
|
||||
ClusterMode = $phSettings.behavior
|
||||
ModerateRemediation = $phSettings.ModerateRemediation
|
||||
SevereRemediation = $phSettings.SevereRemediation
|
||||
HealthProviders = $healthProviders
|
||||
}
|
||||
$pHAConfig
|
||||
} else {
|
||||
Write-Host "Proactive HA has not been configured on this vSphere Cluster"
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-PHAHealth {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to retrieve the Proactive HA health info for all ESXi hosts in vSphere Cluster
|
||||
.PARAMETER Cluster
|
||||
Name of the vSphere Cluster to check Proactive HA health information
|
||||
.EXAMPLE
|
||||
Get-PHAHealth -Cluster VSAN-Cluster
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$Cluster
|
||||
)
|
||||
|
||||
$ClusterView = Get-View -ViewType ClusterComputeResource -Property Name,ConfigurationEx -Filter @{"Name" = $Cluster}
|
||||
|
||||
if($ClusterView -eq $null) {
|
||||
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster $cluster ..."
|
||||
break
|
||||
}
|
||||
|
||||
if($ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers -ne $null) {
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
$providers = $ClusterView.ConfigurationEx.InfraUpdateHaConfig.Providers
|
||||
|
||||
foreach ($provider in $providers) {
|
||||
$providerName = $healthManager.QueryProviderName($provider)
|
||||
$healthUpdates = $healthManager.QueryHealthUpdates($provider)
|
||||
|
||||
$healthResults = @()
|
||||
Write-Host -NoNewline -ForegroundColor Magenta "Health summary for Proactive HA Provider $providerName`:`n"
|
||||
foreach ($healthUpdate in $healthUpdates) {
|
||||
$vmhost = Get-View $healthUpdate.Entity
|
||||
|
||||
$hr = [PSCustomObject] @{
|
||||
Entity = $vmhost.name
|
||||
Status = $healthUpdate.status
|
||||
HealthComponentId = $healthUpdate.HealthUpdateInfoId
|
||||
HealthUpdateId = $healthUpdate.Id
|
||||
Remediation = $healthUpdate.Remediation
|
||||
}
|
||||
$healthResults+=$hr
|
||||
}
|
||||
$healthResults
|
||||
}
|
||||
} else {
|
||||
Write-Host "Proactive HA has not been configured on this vSphere Cluster"
|
||||
}
|
||||
}
|
||||
|
||||
Function New-PHASimulation {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
Function to return VCHA Configuration
|
||||
.PARAMETER ProviderId
|
||||
The Proactive HA Provider ID that you like to simulate a health update from
|
||||
.PARAMETER EsxiHost
|
||||
The name of ESXi host to update the health on
|
||||
.PARAMETER Component
|
||||
The name of the matching component ID from Proactive HA Provider to simulate a health update from
|
||||
.PARAMETER HealthStatus
|
||||
The health value (green, yellow or red) for the given simulated health Update
|
||||
.PARAMETER Remediation
|
||||
The remediation message associated with simulated health update
|
||||
.EXAMPLE
|
||||
New-PHASimulation -EsxiHost vesxi65-4.primp-industries.com -Component Power -HealthStatus green -Remediation "" -ProviderId "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
.EXAMPLE
|
||||
New-PHASimulation -EsxiHost vesxi65-4.primp-industries.com -Component Power -HealthStatus red -Remediation "Please replace my virtual PSU" -ProviderId "52 85 22 c2 f2 6a e7 b9-fc ff 63 9e 10 81 00 79"
|
||||
#>
|
||||
param(
|
||||
[Parameter(Mandatory=$true)][String]$ProviderId,
|
||||
[Parameter(Mandatory=$true)][String]$EsxiHost,
|
||||
[Parameter(Mandatory=$true)][String]$Component,
|
||||
[Parameter(Mandatory=$true)][ValidateSet("green","red","yellow")][String]$HealthStatus,
|
||||
[Parameter(Mandatory=$false)][String]$Remediation
|
||||
)
|
||||
|
||||
Write-Host -ForegroundColor Red "`n******************** DISCLAIMER ********************"
|
||||
Write-Host -ForegroundColor Red "**** THIS IS NOT INTENDED FOR PRODUCTION USE ****"
|
||||
Write-Host -ForegroundColor Red "**** LEARNING PURPOSES ONLY ****"
|
||||
Write-Host -ForegroundColor Red "******************** DISCLAIMER ********************`n"
|
||||
|
||||
$vmhost = Get-View -ViewType HostSystem -Property Name -Filter @{"name" = $EsxiHost}
|
||||
|
||||
if($vmhost -eq $null) {
|
||||
Write-Host -ForegroundColor Red "`nUnable to find ESXi host $EsxiHost ..."
|
||||
break
|
||||
}
|
||||
|
||||
$healthManager = Get-View $global:DefaultVIServer.ExtensionData.Content.HealthUpdateManager
|
||||
|
||||
# Randomly generating an ID for Health Update
|
||||
# In general, you would want to generate a specific ID
|
||||
# which can be referenced between ProactiveHA Provider
|
||||
# and VMware logs for troubleshooting purposes
|
||||
$HealthUpdateID = "vghetto-" + (Get-Random -Minimum 1 -Maximum 100000)
|
||||
|
||||
# All other Health Status can have a remediation message
|
||||
# but for green, it must be an empty string or API call will fail
|
||||
if($HealthStatus -eq "green") {
|
||||
$Remediation = ""
|
||||
}
|
||||
|
||||
$healthUpdate = [VMware.Vim.HealthUpdate] @{
|
||||
Entity = $vmhost.moref
|
||||
HealthUpdateInfoId = $Component
|
||||
Id = $HealthUpdateId
|
||||
Status = $HealthStatus
|
||||
Remediation = $Remediation
|
||||
}
|
||||
|
||||
try {
|
||||
Write-Host "`nSimulating Proactive HA Health Update to ..."
|
||||
Write-Host "`tHost: $EsxiHost "
|
||||
Write-Host -NoNewline "`tStatus: "
|
||||
Write-Host -ForegroundColor $HealthStatus "$HealthStatus"
|
||||
Write-Host "`tRemediation Messsage: $Remediation"
|
||||
$healthManager.PostHealthUpdates($providerId,$healthUpdate)
|
||||
} catch {
|
||||
Write-host -ForegroundColor Red $Error[0].Exception
|
||||
}
|
||||
}
|
||||
227
Modules/Recommend-Sizing/Recommend-Sizing.psm1
Normal file
227
Modules/Recommend-Sizing/Recommend-Sizing.psm1
Normal file
@@ -0,0 +1,227 @@
|
||||
function Recommend-Sizing {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: Markus Kraus
|
||||
Twitter: @VMarkus_K
|
||||
Private Blog: mycloudrevolution.com
|
||||
===========================================================================
|
||||
Changelog:
|
||||
2016.11 ver 1.0 Base Release
|
||||
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, 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
|
||||
===========================================================================
|
||||
Keywords vSphere, ESXi, VM, Storage, Sizing
|
||||
===========================================================================
|
||||
|
||||
.DESCRIPTION
|
||||
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
|
||||
|
||||
.Example
|
||||
Recommend-Sizing -ClusterNames Cluster01, Cluster02
|
||||
|
||||
.Example
|
||||
Recommend-Sizing -ClusterNames Cluster01
|
||||
|
||||
.PARAMETER ClusterNames
|
||||
List of your vSphere Cluser Names to process.
|
||||
|
||||
.PARAMETER Stats
|
||||
Enables Stats Collection.
|
||||
|
||||
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.
|
||||
Default is 24h.
|
||||
|
||||
#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)]
|
||||
[Array] $ClusterNames,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=1, ParameterSetName = "Stats")]
|
||||
[switch] $Stats,
|
||||
[Parameter(Mandatory=$False, ValueFromPipeline=$False, Position=2, ParameterSetName = "Stats")]
|
||||
[int] $StatsRange = 1440
|
||||
|
||||
)
|
||||
Begin {
|
||||
if ($Stats) {
|
||||
Write-Warning "Stats Collection requested.`nAt the moment this is only fully tested with vSphere 5.5 and vSphere 6.5"
|
||||
[int]$TimeRange = "-" + $StatsRange
|
||||
}
|
||||
|
||||
$Validate = $True
|
||||
#region: Check Clusters
|
||||
Write-Verbose "$(Get-Date -Format G) Starting Cluster Validation..."
|
||||
foreach ($ClusterName in $ClusterNames) {
|
||||
$TestCluster = Get-Cluster -Name $ClusterName -ErrorAction SilentlyContinue -Verbose:$False
|
||||
if(!($TestCluster)){
|
||||
Write-Warning "No Custer found wth Name $ClusterName!"
|
||||
$Validate = $False
|
||||
}
|
||||
elseif ($TestCluster.count -gt 1) {
|
||||
Write-Warning "Multiple Custers found wth Name $ClusterName!`nUse a List of explicit Cluster Names: Recommend-Sizing -ClusterNames Cluster01, Cluster02 "
|
||||
$Validate = $False
|
||||
}
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Cluster Validation completed"
|
||||
#endregion
|
||||
}
|
||||
|
||||
Process {
|
||||
$MyView = @()
|
||||
if ($Validate -eq $True) {
|
||||
foreach ($ClusterName in $ClusterNames) {
|
||||
#region: Get Cluster Objects
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $ClusterName Cluster Objects..."
|
||||
$Cluster = Get-Cluster -Name $ClusterName -Verbose:$False
|
||||
$ClusterVMs = $Cluster | Get-VM -Verbose:$False
|
||||
$ClusterVMsPoweredOn = $ClusterVMs | where {$_.PowerState -eq "PoweredOn"}
|
||||
$ClusterDatastores = $Cluster | Get-Datastore -Verbose:$False
|
||||
$ClusterHosts = $Cluster | Get-VMHost -Verbose:$False
|
||||
$HostsAverageMemoryUsageGB = [math]::round( ($ClusterHosts | Measure-Object -Average -Property MemoryUsageGB).Average,1 )
|
||||
$HostsAverageMemoryUsage = $([math]::round( (($ClusterHosts | Measure-Object -Average -Property MemoryUsageGB).Average / ($ClusterHosts | Measure-Object -Average -Property MemoryTotalGB).Average) * 100,1 ))
|
||||
$HostsAverageCpuUsageMhz = [math]::round( ($ClusterHosts | Measure-Object -Average -Property CpuUsageMhz).Average,1 )
|
||||
$HostsAverageCpuUsage = $([math]::round( (($ClusterHosts | Measure-Object -Average -Property CpuUsageMhz).Average / ($ClusterHosts | Measure-Object -Average -Property CpuTotalMhz).Average) * 100,1 ))
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $($Cluster.name) Cluster Objects completed"
|
||||
#endregion
|
||||
|
||||
#region: CPU Calculation
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $($Cluster.name) CPU Details..."
|
||||
$VMvCPUs = ($ClusterVMs | Measure-Object -Sum -Property NumCpu).sum
|
||||
$LogicalThreads = $Cluster.ExtensionData.Summary.NumCpuThreads
|
||||
$CpuCores = $Cluster.ExtensionData.Summary.NumCpuCores
|
||||
$vCPUpCPUratio = [math]::round( $VMvCPUs / $LogicalThreads,1 )
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $($Cluster.name) CPU Details completed."
|
||||
#endregion
|
||||
|
||||
#region: Memory Calculation
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $($Cluster.name) Memory Details..."
|
||||
$AllocatedVMMemoryGB = [math]::round( ($ClusterVMs | Measure-Object -Sum -Property MemoryGB).sum )
|
||||
$PhysicalMemory = [math]::round( $Cluster.ExtensionData.Summary.TotalMemory / 1073741824,1 )
|
||||
$MemoryUsage = [math]::round( ($AllocatedVMMemoryGB / $PhysicalMemory) * 100 ,1 )
|
||||
Write-Verbose "$(Get-Date -Format G) Collect $($Cluster.name) Memory Details completed"
|
||||
#endregion
|
||||
|
||||
if ($Stats) {
|
||||
#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 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) VM Stats Report completed"
|
||||
#endregion
|
||||
}
|
||||
else {
|
||||
Write-Verbose "$(Get-Date -Format G) Stats Collection skipped..."
|
||||
}
|
||||
|
||||
#region: Create VM Disk Space Report
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) VM Disk Space Report..."
|
||||
$reportDiskSpace = @()
|
||||
foreach ($ClusterVM in $ClusterVMs){
|
||||
$VMDKs = $ClusterVM | get-HardDisk -Verbose:$False
|
||||
foreach ($VMDK in $VMDKs) {
|
||||
if ($VMDK -ne $null){
|
||||
[int]$CapacityGB = $VMDK.CapacityKB/1024/1024
|
||||
$Report = [PSCustomObject] @{
|
||||
CapacityGB = $CapacityGB
|
||||
}
|
||||
$reportDiskSpace += $Report
|
||||
}
|
||||
}
|
||||
}
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) VM Disk Space Report completed"
|
||||
#endregion
|
||||
|
||||
#region: Create Datastore Space Report
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) Datastore Space Report..."
|
||||
$DatastoreReport = @($ClusterDatastores | Select-Object @{N="CapacityGB";E={[math]::Round($_.CapacityGB,2)}}, @{N="FreeSpaceGB";E={[math]::Round($_.FreeSpaceGB,2)}}, @{N="UsedSpaceGB";E={[math]::Round($_.CapacityGB - $_.FreeSpaceGB,2)}})
|
||||
Write-Verbose "$(Get-Date -Format G) Process $($Cluster.name) Datastore Space Report completed"
|
||||
#endregion
|
||||
|
||||
#region: Create Global Report
|
||||
Write-Verbose "$(Get-Date -Format G) Process Global Report..."
|
||||
$SizingReport = [PSCustomObject] @{
|
||||
Cluster = $Cluster.name
|
||||
HAEnabled = $Cluster.HAEnabled
|
||||
DrsEnabled = $Cluster.DrsEnabled
|
||||
Hosts = $Cluster.ExtensionData.Summary.NumHosts
|
||||
HostsAverageMemoryUsageGB = $HostsAverageMemoryUsageGB
|
||||
HostsAverageMemoryUsage = "$HostsAverageMemoryUsage %"
|
||||
HostsAverageCpuUsageMhz = $HostsAverageCpuUsageMhz
|
||||
HostsAverageCpuUsage = "$HostsAverageCpuUsage %"
|
||||
PhysicalCPUCores = $CpuCores
|
||||
LogicalCPUThreads = $LogicalThreads
|
||||
VMs = $ClusterVMs.count
|
||||
ActiveVMs = $ClusterVMsPoweredOn.count
|
||||
VMvCPUs = $VMvCPUs
|
||||
vCPUpCPUratio = "$vCPUpCPUratio : 1"
|
||||
PhysicalMemoryGB = $PhysicalMemory
|
||||
AllocatedVMMemoryGB = $AllocatedVMMemoryGB
|
||||
ClusterMemoryUsage = "$MemoryUsage %"
|
||||
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 )
|
||||
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"
|
||||
#endregion
|
||||
}
|
||||
|
||||
}
|
||||
Else {
|
||||
Write-Error "Validation Failed! Processing Skipped"
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
End {
|
||||
$MyView
|
||||
}
|
||||
|
||||
}
|
||||
111
Modules/Set-CBT/Set-CBT.psm1
Normal file
111
Modules/Set-CBT/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/Start-UNMAP.psm1
Normal file
99
Modules/Start-UNMAP/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
|
||||
}
|
||||
|
||||
}
|
||||
716
Modules/VAMI/VAMI.psm1
Executable file
716
Modules/VAMI/VAMI.psm1
Executable file
@@ -0,0 +1,716 @@
|
||||
Function Get-VAMISummary {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves some basic information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return basic VAMI summary info
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMISummary
|
||||
#>
|
||||
$systemVersionAPI = Get-CisService -Name 'com.vmware.appliance.system.version'
|
||||
$results = $systemVersionAPI.get() | select product, type, version, build, install_time
|
||||
|
||||
$systemUptimeAPI = Get-CisService -Name 'com.vmware.appliance.system.uptime'
|
||||
$ts = [timespan]::fromseconds($systemUptimeAPI.get().toString())
|
||||
$uptime = $ts.ToString("hh\:mm\:ss\,fff")
|
||||
|
||||
$summaryResult = [pscustomobject] @{
|
||||
Product = $results.product;
|
||||
Type = $results.type;
|
||||
Version = $results.version;
|
||||
Build = $results.build;
|
||||
InstallTime = $results.install_time;
|
||||
Uptime = $uptime
|
||||
}
|
||||
$summaryResult
|
||||
}
|
||||
|
||||
Function Get-VAMIHealth {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves health information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return VAMI health
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIHealth
|
||||
#>
|
||||
$healthOverall = (Get-CisService -Name 'com.vmware.appliance.health.system').get()
|
||||
$healthLastCheck = (Get-CisService -Name 'com.vmware.appliance.health.system').lastcheck()
|
||||
$healthCPU = (Get-CisService -Name 'com.vmware.appliance.health.load').get()
|
||||
$healthMem = (Get-CisService -Name 'com.vmware.appliance.health.mem').get()
|
||||
$healthSwap = (Get-CisService -Name 'com.vmware.appliance.health.swap').get()
|
||||
$healthStorage = (Get-CisService -Name 'com.vmware.appliance.health.storage').get()
|
||||
|
||||
# DB health only applicable for Embedded/External VCSA Node
|
||||
$vami = (Get-CisService -Name 'com.vmware.appliance.system.version').get()
|
||||
|
||||
if($vami.type -eq "vCenter Server with an embedded Platform Services Controller" -or $vami.type -eq "vCenter Server with an external Platform Services Controller") {
|
||||
$healthVCDB = (Get-CisService -Name 'com.vmware.appliance.health.databasestorage').get()
|
||||
} else {
|
||||
$healthVCDB = "N/A"
|
||||
}
|
||||
$healthSoftwareUpdates = (Get-CisService -Name 'com.vmware.appliance.health.softwarepackages').get()
|
||||
|
||||
$healthResult = [pscustomobject] @{
|
||||
HealthOverall = $healthOverall;
|
||||
HealthLastCheck = $healthLastCheck;
|
||||
HealthCPU = $healthCPU;
|
||||
HealthMem = $healthMem;
|
||||
HealthSwap = $healthSwap;
|
||||
HealthStorage = $healthStorage;
|
||||
HealthVCDB = $healthVCDB;
|
||||
HealthSoftware = $healthSoftwareUpdates
|
||||
}
|
||||
$healthResult
|
||||
}
|
||||
|
||||
Function Get-VAMIAccess {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves access information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return VAMI access interfaces (Console,DCUI,Bash Shell & SSH)
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIAccess
|
||||
#>
|
||||
$consoleAccess = (Get-CisService -Name 'com.vmware.appliance.access.consolecli').get()
|
||||
$dcuiAccess = (Get-CisService -Name 'com.vmware.appliance.access.dcui').get()
|
||||
$shellAccess = (Get-CisService -Name 'com.vmware.appliance.access.shell').get()
|
||||
$sshAccess = (Get-CisService -Name 'com.vmware.appliance.access.ssh').get()
|
||||
|
||||
$accessResult = New-Object PSObject -Property @{
|
||||
Console = $consoleAccess;
|
||||
DCUI = $dcuiAccess;
|
||||
BashShell = $shellAccess.enabled;
|
||||
SSH = $sshAccess
|
||||
}
|
||||
$accessResult
|
||||
}
|
||||
|
||||
Function Get-VAMITime {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the time and NTP info from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return current Time and NTP information
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMITime
|
||||
#>
|
||||
$systemTimeAPI = Get-CisService -Name 'com.vmware.appliance.system.time'
|
||||
$timeResults = $systemTimeAPI.get()
|
||||
|
||||
$timeSync = (Get-CisService -Name 'com.vmware.appliance.techpreview.timesync').get()
|
||||
$timeSyncMode = $timeSync.mode
|
||||
|
||||
$timeResult = [pscustomobject] @{
|
||||
Timezone = $timeResults.timezone;
|
||||
Date = $timeResults.date;
|
||||
CurrentTime = $timeResults.time;
|
||||
Mode = $timeSyncMode;
|
||||
NTPServers = "N/A";
|
||||
NTPStatus = "N/A";
|
||||
}
|
||||
|
||||
if($timeSyncMode -eq "NTP") {
|
||||
$ntpServers = (Get-CisService -Name 'com.vmware.appliance.techpreview.ntp').get()
|
||||
$timeResult.NTPServers = $ntpServers.servers
|
||||
$timeResult.NTPStatus = $ntpServers.status
|
||||
}
|
||||
$timeResult
|
||||
}
|
||||
|
||||
Function Get-VAMINetwork {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves network information from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return networking information including details for each interface
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMINetwork
|
||||
#>
|
||||
$netResults = @()
|
||||
|
||||
$Hostname = (Get-CisService -Name 'com.vmware.appliance.networking.dns.hostname').get()
|
||||
$dns = (Get-CisService -Name 'com.vmware.appliance.networking.dns.servers').get()
|
||||
|
||||
Write-Host "Hostname: " $hostname
|
||||
Write-Host "DNS Servers: " $dns.servers
|
||||
|
||||
$interfaces = (Get-CisService -Name 'com.vmware.appliance.networking.interfaces').list()
|
||||
foreach ($interface in $interfaces) {
|
||||
$ipv4API = (Get-CisService -Name 'com.vmware.appliance.techpreview.networking.ipv4')
|
||||
$spec = $ipv4API.Help.get.interfaces.CreateExample()
|
||||
$spec+= $interface.name
|
||||
$ipv4result = $ipv4API.get($spec)
|
||||
|
||||
$interfaceResult = [pscustomobject] @{
|
||||
Inteface = $interface.name;
|
||||
MAC = $interface.mac;
|
||||
Status = $interface.status;
|
||||
Mode = $ipv4result.mode;
|
||||
IP = $ipv4result.address;
|
||||
Prefix = $ipv4result.prefix;
|
||||
Gateway = $ipv4result.default_gateway;
|
||||
Updateable = $ipv4result.updateable
|
||||
}
|
||||
$netResults += $interfaceResult
|
||||
}
|
||||
$netResults
|
||||
}
|
||||
|
||||
Function Get-VAMIDisks {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves VMDK disk number to partition mapping VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return VMDK disk number to OS partition mapping
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIDisks
|
||||
#>
|
||||
$storageAPI = Get-CisService -Name 'com.vmware.appliance.system.storage'
|
||||
$disks = $storageAPI.list()
|
||||
|
||||
foreach ($disk in $disks | sort {[int]$_.disk.toString()}) {
|
||||
$disk | Select Disk, Partition
|
||||
}
|
||||
}
|
||||
|
||||
Function Start-VAMIDiskResize {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function triggers an OS partition resize after adding additional disk capacity
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function triggers OS partition resize operation
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Start-VAMIDiskResize
|
||||
#>
|
||||
$storageAPI = Get-CisService -Name 'com.vmware.appliance.system.storage'
|
||||
Write-Host "Initiated OS partition resize operation ..."
|
||||
$storageAPI.resize()
|
||||
}
|
||||
|
||||
Function Get-VAMIStatsList {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list avialable monitoring metrics in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of available monitoring metrics that can be queried
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIStatsList
|
||||
#>
|
||||
$monitoringAPI = Get-CisService -Name 'com.vmware.appliance.monitoring'
|
||||
$ids = $monitoringAPI.list() | Select id | Sort-Object -Property id
|
||||
|
||||
foreach ($id in $ids) {
|
||||
$id
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VAMIStorageUsed {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the individaul OS partition storage utilization
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return individual OS partition storage utilization
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIStorageUsed
|
||||
#>
|
||||
$monitoringAPI = Get-CisService 'com.vmware.appliance.monitoring'
|
||||
$querySpec = $monitoringAPI.help.query.item.CreateExample()
|
||||
|
||||
# List of IDs from Get-VAMIStatsList to query
|
||||
$querySpec.Names = @(
|
||||
"storage.used.filesystem.autodeploy",
|
||||
"storage.used.filesystem.boot",
|
||||
"storage.used.filesystem.coredump",
|
||||
"storage.used.filesystem.imagebuilder",
|
||||
"storage.used.filesystem.invsvc",
|
||||
"storage.used.filesystem.log",
|
||||
"storage.used.filesystem.netdump",
|
||||
"storage.used.filesystem.root",
|
||||
"storage.used.filesystem.updatemgr",
|
||||
"storage.used.filesystem.vcdb_core_inventory",
|
||||
"storage.used.filesystem.vcdb_seat",
|
||||
"storage.used.filesystem.vcdb_transaction_log",
|
||||
"storage.totalsize.filesystem.autodeploy",
|
||||
"storage.totalsize.filesystem.boot",
|
||||
"storage.totalsize.filesystem.coredump",
|
||||
"storage.totalsize.filesystem.imagebuilder",
|
||||
"storage.totalsize.filesystem.invsvc",
|
||||
"storage.totalsize.filesystem.log",
|
||||
"storage.totalsize.filesystem.netdump",
|
||||
"storage.totalsize.filesystem.root",
|
||||
"storage.totalsize.filesystem.updatemgr",
|
||||
"storage.totalsize.filesystem.vcdb_core_inventory",
|
||||
"storage.totalsize.filesystem.vcdb_seat",
|
||||
"storage.totalsize.filesystem.vcdb_transaction_log"
|
||||
)
|
||||
|
||||
# Tuple (Filesystem Name, Used, Total) to store results
|
||||
$storageStats = @{
|
||||
"autodeploy"=@{"name"="/storage/autodeploy";"used"=0;"total"=0};
|
||||
"boot"=@{"name"="/boot";"used"=0;"total"=0};
|
||||
"coredump"=@{"name"="/storage/core";"used"=0;"total"=0};
|
||||
"imagebuilder"=@{"name"="/storage/imagebuilder";"used"=0;"total"=0};
|
||||
"invsvc"=@{"name"="/storage/invsvc";"used"=0;"total"=0};
|
||||
"log"=@{"name"="/storage/log";"used"=0;"total"=0};
|
||||
"netdump"=@{"name"="/storage/netdump";"used"=0;"total"=0};
|
||||
"root"=@{"name"="/";"used"=0;"total"=0};
|
||||
"updatemgr"=@{"name"="/storage/updatemgr";"used"=0;"total"=0};
|
||||
"vcdb_core_inventory"=@{"name"="/storage/db";"used"=0;"total"=0};
|
||||
"vcdb_seat"=@{"name"="/storage/seat";"used"=0;"total"=0};
|
||||
"vcdb_transaction_log"=@{"name"="/storage/dblog";"used"=0;"total"=0}
|
||||
}
|
||||
|
||||
$querySpec.interval = "DAY1"
|
||||
$querySpec.function = "MAX"
|
||||
$querySpec.start_time = ((get-date).AddDays(-1))
|
||||
$querySpec.end_time = (Get-Date)
|
||||
$queryResults = $monitoringAPI.query($querySpec) | Select * -ExcludeProperty Help
|
||||
|
||||
foreach ($queryResult in $queryResults) {
|
||||
# Update hash if its used storage results
|
||||
if($queryResult.name -match "used") {
|
||||
$key = (($queryResult.name).toString()).split(".")[-1]
|
||||
$value = [Math]::Round([int]($queryResult.data[1]).toString()/1MB,2)
|
||||
$storageStats[$key]["used"] = $value
|
||||
# Update hash if its total storage results
|
||||
} else {
|
||||
$key = (($queryResult.name).toString()).split(".")[-1]
|
||||
$value = [Math]::Round([int]($queryResult.data[1]).toString()/1MB,2)
|
||||
$storageStats[$key]["total"] = $value
|
||||
}
|
||||
}
|
||||
|
||||
$storageResults = @()
|
||||
foreach ($key in $storageStats.keys | Sort-Object -Property name) {
|
||||
$statResult = [pscustomobject] @{
|
||||
Filesystem = $storageStats[$key].name;
|
||||
Used = $storageStats[$key].used;
|
||||
Total = $storageStats[$key].total
|
||||
}
|
||||
$storageResults += $statResult
|
||||
}
|
||||
$storageResults
|
||||
}
|
||||
|
||||
Function Get-VAMIService {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list of services in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of services and their description
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIService
|
||||
.EXAMPLE
|
||||
Get-VAMIService -Name rbd
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$false,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
if($Name -ne "") {
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
|
||||
try {
|
||||
$serviceStatus = $vMonAPI.get($name,0)
|
||||
$serviceString = [pscustomobject] @{
|
||||
Name = $name;
|
||||
State = $serviceStatus.state;
|
||||
Health = "";
|
||||
Startup = $serviceStatus.startup_type
|
||||
}
|
||||
if($serviceStatus.health -eq $null) { $serviceString.Health = "N/A"} else { $serviceString.Health = $serviceStatus.health }
|
||||
$serviceString
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
} else {
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
$services = $vMonAPI.list_details()
|
||||
|
||||
$serviceResult = @()
|
||||
foreach ($key in $services.keys | Sort-Object -Property Value) {
|
||||
$serviceString = [pscustomobject] @{
|
||||
Name = $key;
|
||||
State = $services[$key].state;
|
||||
Health = "N/A";
|
||||
Startup = $services[$key].Startup_type
|
||||
}
|
||||
if($services[$key].health -eq $null) { $serviceString.Health = "N/A"} else { $serviceString.Health = $services[$key].health }
|
||||
|
||||
$serviceResult += $serviceString
|
||||
}
|
||||
$serviceResult
|
||||
}
|
||||
}
|
||||
|
||||
Function Start-VAMIService {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list of services in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of services and their description
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Start-VAMIService -Name rbd
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
|
||||
try {
|
||||
Write-Host "Starting $name service ..."
|
||||
$vMonAPI.start($name)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
|
||||
Function Stop-VAMIService {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves list of services in VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return list of services and their description
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Stop-VAMIService -Name rbd
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
|
||||
|
||||
try {
|
||||
Write-Host "Stopping $name service ..."
|
||||
$vMonAPI.stop($name)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
|
||||
Function Get-VAMIBackupSize {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves the backup size of the VCSA from VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to return the current backup size of the VCSA (common and core data)
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIBackupSize
|
||||
#>
|
||||
$recoveryAPI = Get-CisService 'com.vmware.appliance.recovery.backup.parts'
|
||||
$backupParts = $recoveryAPI.list() | select id
|
||||
|
||||
$estimateBackupSize = 0
|
||||
$backupPartSizes = ""
|
||||
foreach ($backupPart in $backupParts) {
|
||||
$partId = $backupPart.id.value
|
||||
$partSize = $recoveryAPI.get($partId)
|
||||
$estimateBackupSize += $partSize
|
||||
$backupPartSizes += $partId + " data is " + $partSize + " MB`n"
|
||||
}
|
||||
|
||||
Write-Host "Estimated Backup Size: $estimateBackupSize MB"
|
||||
Write-Host $backupPartSizes
|
||||
}
|
||||
|
||||
Function Get-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function retrieves VAMI local users using VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to retrieve VAMI local users
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIUser
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$false,
|
||||
ValueFromPipeline=$true,
|
||||
ValueFromPipelineByPropertyName=$true)
|
||||
]
|
||||
[String]$Name
|
||||
)
|
||||
|
||||
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
|
||||
|
||||
$userResults = @()
|
||||
|
||||
if($Name -ne "") {
|
||||
try {
|
||||
$user = $userAPI.get($name)
|
||||
|
||||
$userString = [pscustomobject] @{
|
||||
User = $user.username
|
||||
Name = $user.fullname
|
||||
Email = $user.email
|
||||
Status = $user.status
|
||||
PasswordStatus = $user.passwordstatus
|
||||
Role = $user.role
|
||||
}
|
||||
$userResults += $userString
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
} else {
|
||||
$users = $userAPI.list()
|
||||
|
||||
foreach ($user in $users) {
|
||||
$userString = [pscustomobject] @{
|
||||
User = $user.username
|
||||
Name = $user.fullname
|
||||
Email = $user.email
|
||||
Status = $user.status
|
||||
PasswordStatus = $user.passwordstatus
|
||||
Role = $user.role
|
||||
}
|
||||
$userResults += $userString
|
||||
}
|
||||
}
|
||||
$userResults
|
||||
}
|
||||
|
||||
Function New-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function to create new VAMI local user using VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to create a new VAMI local user
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
New-VAMIUser -name lamw -fullname "William Lam" -role "operator" -email "lamw@virtuallyghetto.com" -password "VMware1!"
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$name,
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$fullname,
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[ValidateSet("admin","operator","superAdmin")][String]$role,
|
||||
[Parameter(
|
||||
Mandatory=$false)
|
||||
]
|
||||
[String]$email="",
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$password
|
||||
)
|
||||
|
||||
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
|
||||
$createSpec = $userAPI.Help.add.config.CreateExample()
|
||||
|
||||
$createSpec.username = $name
|
||||
$createSpec.fullname = $fullname
|
||||
$createSpec.role = $role
|
||||
$createSpec.email = $email
|
||||
$createSpec.password = [VMware.VimAutomation.Cis.Core.Types.V1.Secret]$password
|
||||
|
||||
try {
|
||||
Write-Host "Creating new user $name ..."
|
||||
$userAPI.add($createSpec)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
|
||||
Function Remove-VAMIUser {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created by: William Lam
|
||||
Organization: VMware
|
||||
Blog: www.virtuallyghetto.com
|
||||
Twitter: @lamw
|
||||
===========================================================================
|
||||
.SYNOPSIS
|
||||
This function to remove VAMI local user using VAMI interface (5480)
|
||||
for a VCSA node which can be an Embedded VCSA, External PSC or External VCSA.
|
||||
.DESCRIPTION
|
||||
Function to remove VAMI local user
|
||||
.EXAMPLE
|
||||
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
|
||||
Get-VAMIAccess
|
||||
#>
|
||||
param(
|
||||
[Parameter(
|
||||
Mandatory=$true)
|
||||
]
|
||||
[String]$name,
|
||||
[Parameter(
|
||||
Mandatory=$false)
|
||||
]
|
||||
[boolean]$confirm=$false
|
||||
)
|
||||
|
||||
if(!$confirm) {
|
||||
$answer = Read-Host -Prompt "Do you want to delete user $name (Y or N)"
|
||||
if($answer -eq "Y" -or $answer -eq "y") {
|
||||
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
|
||||
|
||||
try {
|
||||
Write-Host "Deleting user $name ..."
|
||||
$userAPI.delete($name)
|
||||
} catch {
|
||||
Write-Error $Error[0].exception.Message
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
413
Modules/VCHA/VCHA.psm1
Normal file
413
Modules/VCHA/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
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
322
Modules/VMCPFunctions/VMCPFunctions.psm1
Normal file
322
Modules/VMCPFunctions/VMCPFunctions.psm1
Normal file
@@ -0,0 +1,322 @@
|
||||
function Get-VMCPSettings {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 10/27/2015 9:25 PM
|
||||
Created by: Brian Graf
|
||||
Twitter: @vBrianGraf
|
||||
VMware Blog: blogs.vmware.com/powercli
|
||||
Personal Blog: www.vtagion.com
|
||||
|
||||
Modified on: 10/11/2016
|
||||
Modified by: Erwan Quélin
|
||||
Twitter: @erwanquelin
|
||||
Github: https://github.com/equelin
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function will allow users to view the VMCP settings for their clusters
|
||||
|
||||
.PARAMETER Cluster
|
||||
Cluster Name or Object
|
||||
|
||||
.PARAMETER Server
|
||||
vCenter server object
|
||||
|
||||
.EXAMPLE
|
||||
Get-VMCPSettings
|
||||
|
||||
This will show you the VMCP settings for all the clusters
|
||||
|
||||
.EXAMPLE
|
||||
Get-VMCPSettings -cluster LAB-CL
|
||||
|
||||
This will show you the VMCP settings of your cluster
|
||||
|
||||
.EXAMPLE
|
||||
Get-VMCPSettings -cluster (Get-Cluster Lab-CL)
|
||||
|
||||
This will show you the VMCP settings of your cluster
|
||||
|
||||
.EXAMPLE
|
||||
Get-Cluster | Get-VMCPSettings
|
||||
|
||||
This will show you the VMCP settings for all the clusters
|
||||
#>
|
||||
[CmdletBinding()]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$True,
|
||||
ValueFromPipelineByPropertyName=$True,
|
||||
HelpMessage='What is the Cluster Name?')]
|
||||
$cluster = (Get-Cluster -Server $Server),
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[VMware.VimAutomation.Types.VIServer[]]$Server = $global:DefaultVIServers
|
||||
)
|
||||
|
||||
Process {
|
||||
|
||||
Foreach ($Clus in $Cluster) {
|
||||
|
||||
Write-Verbose "Processing Cluster $($Clus.Name)"
|
||||
|
||||
# Determine input and convert to ClusterImpl object
|
||||
Switch ($Clus.GetType().Name)
|
||||
{
|
||||
"string" {$CL = Get-Cluster $Clus -Server $Server -ErrorAction SilentlyContinue}
|
||||
"ClusterImpl" {$CL = $Clus}
|
||||
}
|
||||
|
||||
If ($CL) {
|
||||
# Work with the Cluster View
|
||||
$ClusterMod = Get-View -Id "ClusterComputeResource-$($CL.ExtensionData.MoRef.Value)" -Server $Server
|
||||
|
||||
# Create Hashtable with desired properties to return
|
||||
$properties = [ordered]@{
|
||||
'Cluster' = $ClusterMod.Name;
|
||||
'VMCP Status' = $clustermod.Configuration.DasConfig.VmComponentProtecting;
|
||||
'Protection For APD' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForAPD;
|
||||
'APD Timeout Enabled' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.EnableAPDTimeoutForHosts;
|
||||
'APD Timeout (Seconds)' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmTerminateDelayForAPDSec;
|
||||
'Reaction on APD Cleared' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmReactionOnAPDCleared;
|
||||
'Protection For PDL' = $clustermod.Configuration.DasConfig.DefaultVmSettings.VmComponentProtectionSettings.VmStorageProtectionForPDL
|
||||
}
|
||||
|
||||
# Create PSObject with the Hashtable
|
||||
$object = New-Object -TypeName PSObject -Prop $properties
|
||||
|
||||
# Show object
|
||||
$object
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Set-VMCPSettings {
|
||||
<#
|
||||
.NOTES
|
||||
===========================================================================
|
||||
Created on: 10/27/2015 9:25 PM
|
||||
Created by: Brian Graf
|
||||
Twitter: @vBrianGraf
|
||||
VMware Blog: blogs.vmware.com/powercli
|
||||
Personal Blog: www.vtagion.com
|
||||
|
||||
Modified on: 10/11/2016
|
||||
Modified by: Erwan Quélin
|
||||
Twitter: @erwanquelin
|
||||
Github: https://github.com/equelin
|
||||
===========================================================================
|
||||
.DESCRIPTION
|
||||
This function will allow users to enable/disable VMCP and also allow
|
||||
them to configure the additional VMCP settings
|
||||
For each parameter, users should use the 'Tab' button to auto-fill the
|
||||
possible values.
|
||||
|
||||
.PARAMETER Cluster
|
||||
Cluster Name or Object
|
||||
|
||||
.PARAMETER enableVMCP
|
||||
Enable or disable VMCP
|
||||
|
||||
.PARAMETER VmStorageProtectionForPDL
|
||||
VM Storage Protection for PDL settings. Might be:
|
||||
- disabled
|
||||
- warning
|
||||
- restartAggressive
|
||||
|
||||
.PARAMETER VmStorageProtectionForAPD
|
||||
VM Storage Protection for APD settings. Might be:
|
||||
- disabled
|
||||
- restartConservative
|
||||
- restartAggressive
|
||||
- warning
|
||||
|
||||
.PARAMETER VmTerminateDelayForAPDSec
|
||||
VM Terminate Delay for APD (seconds).
|
||||
|
||||
.PARAMETER VmReactionOnAPDCleared
|
||||
VM reaction on APD Cleared. Might be:
|
||||
- reset
|
||||
- none
|
||||
|
||||
.PARAMETER Server
|
||||
vCenter server object
|
||||
|
||||
.EXAMPLE
|
||||
Set-VMCPSettings -cluster LAB-CL -enableVMCP:$True -VmStorageProtectionForPDL `
|
||||
restartAggressive -VmStorageProtectionForAPD restartAggressive `
|
||||
-VmTerminateDelayForAPDSec 2000 -VmReactionOnAPDCleared reset
|
||||
|
||||
This will enable VMCP and configure the Settings on cluster LAB-CL
|
||||
|
||||
.EXAMPLE
|
||||
Set-VMCPSettings -cluster LAB-CL -enableVMCP:$False -VmStorageProtectionForPDL `
|
||||
disabled -VmStorageProtectionForAPD disabled `
|
||||
-VmTerminateDelayForAPDSec 600 -VmReactionOnAPDCleared none
|
||||
|
||||
This will disable VMCP and configure the Settings on cluster LAB-CL
|
||||
|
||||
.EXAMPLE
|
||||
Set-VMCPSettings -enableVMCP:$False -VmStorageProtectionForPDL `
|
||||
disabled -VmStorageProtectionForAPD disabled `
|
||||
-VmTerminateDelayForAPDSec 600 -VmReactionOnAPDCleared none
|
||||
|
||||
This will disable VMCP and configure the Settings on all clusters available
|
||||
#>
|
||||
[CmdletBinding(SupportsShouldProcess=$true,ConfirmImpact="High")]
|
||||
param
|
||||
(
|
||||
[Parameter(Mandatory=$true,
|
||||
ValueFromPipeline=$True,
|
||||
ValueFromPipelineByPropertyName=$True,
|
||||
HelpMessage='What is the Cluster Name?')]
|
||||
$cluster,
|
||||
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='$True=Enabled $False=Disabled')]
|
||||
[bool]$enableVMCP,
|
||||
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Actions that can be taken in response to a PDL event')]
|
||||
[ValidateSet("disabled","warning","restartAggressive")]
|
||||
[string]$VmStorageProtectionForPDL,
|
||||
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Options available for an APD response')]
|
||||
[ValidateSet("disabled","restartConservative","restartAggressive","warning")]
|
||||
[string]$VmStorageProtectionForAPD,
|
||||
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='Value in seconds')]
|
||||
[Int]$VmTerminateDelayForAPDSec,
|
||||
|
||||
[Parameter(Mandatory=$False,
|
||||
ValueFromPipeline=$False,
|
||||
HelpMessage='This setting will instruct vSphere HA to take a certain action if an APD event is cleared')]
|
||||
[ValidateSet("reset","none")]
|
||||
[string]$VmReactionOnAPDCleared,
|
||||
|
||||
[Parameter(Mandatory=$False)]
|
||||
[VMware.VimAutomation.Types.VIServer[]]$Server = $global:DefaultVIServers
|
||||
)
|
||||
|
||||
Process {
|
||||
|
||||
Foreach ($Clus in $Cluster) {
|
||||
|
||||
Write-Verbose "Processing Cluster $Clus"
|
||||
|
||||
# Determine input and convert to ClusterImpl object
|
||||
Switch ($Clus.GetType().Name)
|
||||
{
|
||||
"string" {$CL = Get-Cluster $Clus -Server $Server -ErrorAction SilentlyContinue}
|
||||
"ClusterImpl" {$CL = $Clus}
|
||||
default {Throw 'Please provide a cluster name or object'}
|
||||
}
|
||||
|
||||
If ($CL) {
|
||||
|
||||
# Get the actual configuration of the Cluster
|
||||
$ActualSettings = Get-VMCPSettings -Cluster $CL -Server $Server
|
||||
|
||||
# Show actual settings in the verbose mode
|
||||
Write-Verbose "[$($CL.Name)] Actual VMCP settings "
|
||||
Write-Verbose $ActualSettings
|
||||
|
||||
# Create the object we will configure
|
||||
$settings = New-Object VMware.Vim.ClusterConfigSpecEx
|
||||
$settings.dasConfig = New-Object VMware.Vim.ClusterDasConfigInfo
|
||||
|
||||
# Based on $enableVMCP switch
|
||||
if ($enableVMCP -eq $false) {
|
||||
$settings.dasConfig.vmComponentProtecting = "disabled"
|
||||
}
|
||||
elseif ($enableVMCP -eq $true) {
|
||||
$settings.dasConfig.vmComponentProtecting = "enabled"
|
||||
}
|
||||
|
||||
#Create the VMCP object to work with
|
||||
$settings.dasConfig.defaultVmSettings = New-Object VMware.Vim.ClusterDasVmSettings
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings = New-Object VMware.Vim.ClusterVmComponentProtectionSettings
|
||||
|
||||
#Storage Protection For PDL
|
||||
If ($PSBoundParameters.ContainsKey('VmStorageProtectionForPDL')) {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForPDL = $VmStorageProtectionForPDL
|
||||
} else {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForPDL = $ActualSettings.'Protection For PDL'
|
||||
}
|
||||
|
||||
#Storage Protection for APD
|
||||
If ($PSBoundParameters.ContainsKey('VmStorageProtectionForAPD')) {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = $VmStorageProtectionForAPD
|
||||
} else {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = $ActualSettings.'Protection For APD'
|
||||
}
|
||||
|
||||
#Storage Protection for APD
|
||||
If ($PSBoundParameters.ContainsKey('VmStorageProtectionForAPD')) {
|
||||
switch ($VmStorageProtectionForAPD) {
|
||||
"disabled" {
|
||||
# If Disabled, there is no need to set enable Timeout Value
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'disabled'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $false
|
||||
}
|
||||
|
||||
"restartConservative" {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'restartConservative'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $true
|
||||
}
|
||||
|
||||
"restartAggressive" {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'restartAggressive'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $true
|
||||
}
|
||||
|
||||
"warning" {
|
||||
# If Warning, there is no need to enable the Timeout Value
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = 'warning'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $false
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmStorageProtectionForAPD = $ActualSettings.'Protection For APD'
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.enableAPDTimeoutForHosts = $ActualSettings.'APD Timeout Enabled'
|
||||
}
|
||||
|
||||
#APD Timeout Enabled
|
||||
If ($PSBoundParameters.ContainsKey('VmTerminateDelayForAPDSec')) {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmTerminateDelayForAPDSec = $VmTerminateDelayForAPDSec
|
||||
} else {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmTerminateDelayForAPDSec = $ActualSettings.'APD Timeout (Seconds)'
|
||||
}
|
||||
|
||||
# Reaction On APD Cleared
|
||||
If ($PSBoundParameters.ContainsKey('VmReactionOnAPDCleared')) {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmReactionOnAPDCleared = "$VmReactionOnAPDCleared"
|
||||
} else {
|
||||
$settings.dasConfig.defaultVmSettings.vmComponentProtectionSettings.vmReactionOnAPDCleared = $ActualSettings.'Reaction on APD Cleared'
|
||||
}
|
||||
|
||||
# Execute API Call
|
||||
If ($pscmdlet.ShouldProcess($CL.Name,"Modify VMCP configuration")) {
|
||||
$modify = $true
|
||||
$ClusterMod = Get-View -Id "ClusterComputeResource-$($CL.ExtensionData.MoRef.Value)" -Server $Server
|
||||
$Task = $ClusterMod.ReconfigureComputeResource_Task($settings, $modify)
|
||||
}
|
||||
|
||||
# Wait for the reconfiguration task to finish to show the result
|
||||
If ($Task) {
|
||||
$TaskID = "Task-" + $($Task.Value)
|
||||
Get-Task -Id $TaskID -Server $Server | Wait-Task | Out-Null
|
||||
Get-VMCPSettings -Cluster $CL -Server $Server
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
93
Modules/apply-hardening/apply-hardening.psm1
Normal file
93
Modules/apply-hardening/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
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user