Merge branch 'master' into master

This commit is contained in:
dmilov
2020-09-23 10:15:25 +03:00
committed by GitHub
20 changed files with 2624 additions and 318 deletions

View File

@@ -1,204 +1,539 @@
Function Backup-VCSAToFile {
Function Backup-VCSAToFile {
<#
.NOTES
===========================================================================
.NOTES
===========================================================================
Created by: Brian Graf
Date: October 30, 2016
Date: October 30, 2016
Organization: VMware
Blog: www.vtagion.com
Twitter: @vBrianGraf
Blog: www.vtagion.com
Twitter: @vBrianGraf
Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.SYNOPSIS
This function will allow you to create a full or partial backup of your
VCSA appliance. (vSphere 6.5 and higher)
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"
[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
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
A CisService can also be supplied as a parameter.
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
-CommonBackup will only backup the config whereas -Fullbackup grabs the historical data as well
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
-CommonBackup will only backup the config whereas -Fullbackup grabs the historical data as well
#>
param (
[Parameter(ParameterSetName=FullBackup)]
[switch]$FullBackup,
[Parameter(ParameterSetName=CommonBackup)]
[switch]$CommonBackup,
[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)){
Add-Type -Assembly System.Windows.Forms
[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 ($CommonBackup) {$parts = @("common")}
}
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 {
throw $_.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")
Write-Progress -Activity "Backing up VCSA" -Completed
$BackupAPI.get("$($BackupJob.ID)") | select id, progress, state
}
Else {
$BackupJob | select id, progress, state
}
}
End {}
param (
[Parameter(ParameterSetName=FullBackup)]
[switch]$FullBackup,
[Parameter(ParameterSetName=CommonBackup)]
[switch]$CommonBackup,
[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",
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers,
[switch]$ShowProgress
)
Begin {
if ($CisServer.IsConnected) {
Write-Verbose "Connected to $($CisServer.Name)"
$connection = $CisServer
} elseif ($CisServer.gettype().name -eq "String") {
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
$Connection = Connect-CisServer $CisServer
} elseif ($global:DefaultCisServers) {
$connection = $global:DefaultCisServers
} elseif ($global:DefaultVIServer) {
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
$Connection = Connect-CisServer $global:DefaultVIServer
}
if (!$Connection) {
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
}
if ($FullBackup) {$parts = @("common","seat")}
if ($CommonBackup) {$parts = @("common")}
}
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 {
throw $_.Exception.Message
}
If ($ShowProgress){
do {
$BackupAPI.get("$($BackupJob.ID)") | Select-Object 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")
Write-Progress -Activity "Backing up VCSA" -Completed
$BackupAPI.get("$($BackupJob.ID)") | Select-Object id, progress, state
} Else {
$BackupJob | Select-Object id, progress, state
}
}
End {}
}
Function Get-VCSABackupJobs {
<#
.NOTES
===========================================================================
Created by: Brian Graf
Date: October 30, 2016
Organization: VMware
Blog: www.vtagion.com
Twitter: @vBrianGraf
.NOTES
===========================================================================
Created by: Brian Graf
Date: October 30, 2016
Organization: VMware
Blog: www.vtagion.com
Twitter: @vBrianGraf
Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.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
.EXAMPLE
PS C:\> Get-VCSABackupJobs -ShowNewest -CisServer "vcserver.sphere.local"
.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
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 {}
param (
[Parameter(Mandatory=$false)][switch]$ShowNewest,
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers
)
Begin {
if ($CisServer.IsConnected) {
Write-Verbose "Connected to $($CisServer.Name)"
$connection = $CisServer
} elseif ($CisServer.gettype().name -eq "String") {
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
$Connection = Connect-CisServer $CisServer
} elseif ($global:DefaultCisServers) {
$connection = $global:DefaultCisServers
} elseif ($global:DefaultVIServer) {
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
$Connection = Connect-CisServer $global:DefaultVIServer
}
if (!$Connection) {
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
}
}
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
.NOTES
===========================================================================
Created by: Brian Graf
Date: October 30, 2016
Organization: VMware
Blog: www.vtagion.com
Twitter: @vBrianGraf
Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.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
.EXAMPLE
PS C:\> $backups = Get-VCSABackupJobs
$backups[0] | Get-VCSABackupStatus
$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 {}
Param (
[parameter(Mandatory=$false,ValueFromPipeline=$True)][string[]]$BackupID,
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers
)
Begin {
if ($CisServer.IsConnected) {
Write-Verbose "Connected to $($CisServer.Name)"
$connection = $CisServer
} elseif ($CisServer.gettype().name -eq "String") {
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
$Connection = Connect-CisServer $CisServer
} elseif ($global:DefaultCisServers) {
$connection = $global:DefaultCisServers
} elseif ($global:DefaultVIServer) {
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
$Connection = Connect-CisServer $global:DefaultVIServer
}
if (!$Connection) {
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
}
}
Process{
$BackupAPI = Get-CisService 'com.vmware.appliance.recovery.backup.job'
Foreach ($id in $BackupID) {
$BackupAPI.get("$id") | Select-Object id, progress, state
}
}
End {}
}
Function New-VCSASchedule {
<#
.NOTES
===========================================================================
Original Created by: Brian Graf
Blog: www.vtagion.com
Twitter: @vBrianGraf
Organization: VMware
Created / Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.SYNOPSIS
This function will allow you to create a scheduled to backup your
VCSA appliance. (vSphere 6.7 and higher)
.DESCRIPTION
Use this function to create a schedule to backup your VCSA to a remote location
.EXAMPLE
The Below Create a schedule on Monday @11:30pm to FTP location 10.1.1.10:/vcsabackup/vcenter01
and keep 4 backups with a Encryption Passowrd of "VMw@re123"
$location = "ftp://10.1.1.10/vcsabackup/vcenter01"
$LocationUser = "admin"
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$locationPassword = "VMw@re123"
$BHour = 23
$BMin = 30
$BDays = @("Monday")
$MaxCount = 4
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword = "VMw@re123"
PS C:\> New-VCSASchedule -Location $location -LocationUser $LocationUser -LocationPassword $locationPassword -BackupHour $BHour -BackupMinute $BMin -backupDays $BDays -MaxCount $MaxCount -BackupPassword $BackupPassword
.EXAMPLE
The Below Create a schedule on Sunday & Wednesday @5:15am
to NFS location 10.1.1.10:/vcsabackup/vcenter01
keep 10 backups with a Encryption Passowrd of "VMw@re123"
with Event Data included (Seat) and will delete any existing schedule.
$location = "nfs://10.1.1.10/vcsabackup/vcenter01"
$LocationUser = "admin"
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$locationPassword = "VMw@re123"
$BHour = 5
$BMin = 15
$BDays = @("Sunday", "Monday")
$MaxCount = 10
[VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword = "VMw@re123"
PS C:\> New-VCSASchedule -IncludeSeat -force -Location $location -LocationUser $LocationUser -LocationPassword $locationPassword -BackupHour $BHour -BackupMinute $BMin -backupDays $BDays -MaxCount $MaxCount -BackupPassword $BackupPassword -CisServer "vcserver.sphere.local"
.NOTES
Credit goes to @AlanRenouf & @vBrianGraf for sharing the base of this function.
You must be connected to the CisService for this to work, if you are not connected, the function will prompt you for your credentials
#>
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'Medium')]
param (
[Parameter(Mandatory=$true)]$Location,
[Parameter(Mandatory=$true)]$LocationUser,
[Parameter(Mandatory=$true)][VMware.VimAutomation.Cis.Core.Types.V1.Secret]$LocationPassword,
[Parameter(Mandatory=$true)][VMware.VimAutomation.Cis.Core.Types.V1.Secret]$BackupPassword,
[Parameter(Mandatory=$true)][ValidateRange(0,23)]$BackupHour,
[Parameter(Mandatory=$true)][ValidateRange(0,59)]$BackupMinute,
[Parameter(Mandatory=$true)][ValidateSet('Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday')][Array]$BackupDays = $null,
[Parameter(Mandatory=$true)][Integer]$MaxCount,
[Parameter(Mandatory=$false)]$BackupID = "default",
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers,
[Parameter(Mandatory=$false)][switch]$IncludeSeat,
[Parameter(Mandatory=$false)][switch]$Force
)
Begin {
if ($CisServer.IsConnected) {
Write-Verbose "Connected to $($CisServer.Name)"
$connection = $CisServer
} elseif ($CisServer.gettype().name -eq "String") {
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
$Connection = Connect-CisServer $CisServer
} elseif ($global:DefaultCisServers) {
$connection = $global:DefaultCisServers
} elseif ($global:DefaultVIServer) {
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
$Connection = Connect-CisServer $global:DefaultVIServer
}
if (!$Connection) {
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
}
}
Process{
if (!(Test-VCSAScheduleSupport)) {
Write-Error "This VCSA does not support Backup Schedules."
return
}
$BackupAPI = Get-CisService -name 'com.vmware.appliance.recovery.backup.schedules'
$CreateSpec = $BackupAPI.Help.create.spec.Create()
$CreateSpec.backup_password = $BackupPassword
$CreateSpec.location = $Location
$CreateSpec.location_user = $LocationUser
$CreateSpec.location_password = $LocationPassword
$CreateSpec.Enable = $true
$CreateSpec.recurrence_info.Hour = $BackupHour
$CreateSpec.recurrence_info.Minute = $BackupMinute
$CreateSpec.recurrence_info.Days = $BackupDays
$CreateSpec.retention_info.max_count = $MaxCount
if ($IncludeSeat) {
$CreateSpec.parts = @("seat")
} else {
$CreateSpec.parts = @()
}
$CurrentSchedule = $BackupAPI.list()
if ($CurrentSchedule.keys.value) {
if($Force -or $PSCmdlet.ShouldContinue($CurrentSchedule.keys.value,'Delete Old Schedule')){
$BackupAPI.delete($CurrentSchedule.keys.value)
} else {
Write-Error "There is an exisiting Schedule. Please delete before Creating a new one."
return
}
}
if ($PSCmdlet.ShouldProcess($BackupID, 'Create New Schedule.')) {
try {
$BackupJob = $BackupAPI.create($BackupID, $CreateSpec)
}
catch {
throw $_.Exception.Message
}
}
if ($BackupJob) {
Write-Host "Backup up Job Created."
return $BackupJob
}
}
End {}
}
Function Get-VCSASchedule {
<#
.NOTES
===========================================================================
Original Created by: Brian Graf
Blog: www.vtagion.com
Twitter: @vBrianGraf
Organization: VMware
Created / Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.SYNOPSIS
This function will allow you to Get the scheduled backup of your
VCSA appliance. (vSphere 6.7 and higher)
.DESCRIPTION
Use this function to Get the backup schedule for your VCSA appliance.
.EXAMPLE
PS C:\> Get-VCSASchedule
.EXAMPLE
PS C:\> Get-VCSASchedule -ScheduleID 1 -CisServer "vcserver.sphere.local"
.NOTES
Credit goes to @AlanRenouf & @vBrianGraf for sharing the base of this function.
Returns a simplified object with the schedule details.
You must be connected to the CisService for this to work, if you are not connected, the function will prompt you for your credentials
#>
param (
[Parameter(Mandatory=$False,HelpMessage="Will Filter List By ScheduleID")]$ScheduleID,
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers
)
Begin {
if ($CisServer.IsConnected) {
Write-Verbose "Connected to $($CisServer.Name)"
$connection = $CisServer
} elseif ($CisServer.gettype().name -eq "String") {
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
$Connection = Connect-CisServer $CisServer
} elseif ($global:DefaultCisServers) {
$connection = $global:DefaultCisServers
} elseif ($global:DefaultVIServer) {
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
$Connection = Connect-CisServer $global:DefaultVIServer
}
if (!$Connection) {
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
}
}
Process{
if (!(Test-VCSAScheduleSupport)) {
Write-Error "This VCSA does not support Backup Schedules."
return
}
$BackupAPI = Get-CisService -name 'com.vmware.appliance.recovery.backup.schedules'
$Schedules = $BackupAPI.list()
if ($Schedules.count -ge 1) {
$ObjSchedule = @()
foreach ($Schedule in $Schedules) {
$ObjSchedule += $Schedule.values | Select-Object *,@{N = "ID"; e = {"$($schedule.keys.value)"}} -ExpandProperty recurrence_info -ExcludeProperty Help | Select-Object * -ExcludeProperty recurrence_info,Help | Select-Object * -ExpandProperty retention_info | Select-Object * -ExcludeProperty retention_info,Help
}
if ($ScheduleID) {
$ObjSchedule = $ObjSchedule | Where-Object {$_.ID -eq $ScheduleID}
}
return $ObjSchedule
} else {
Write-Information "No Schedule Defined."
}
}
End {}
}
Function Remove-VCSASchedule {
<#
.NOTES
===========================================================================
Original Created by: Brian Graf
Blog: www.vtagion.com
Twitter: @vBrianGraf
Organization: VMware
Created / Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
============================================================================
.SYNOPSIS
This function will remove any scheduled backups of your
VCSA appliance. (vSphere 6.7 and higher)
.DESCRIPTION
Use this function to remove the backup schedule for your VCSA appliance.
.EXAMPLE
PS C:\> Remove-VCSASchedule
.EXAMPLE
PS C:\> Remove-VCSASchedule -ScheduleID 1 -CisServer "vcserver.sphere.local"
.NOTES
Credit goes to @AlanRenouf & @vBrianGraf for sharing the base of this function.
You must be connected to the CisService for this to work, if you are not connected, the function will prompt you for your credentials
#>
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
param (
[Parameter(Mandatory=$false)]$ScheduleID = "default",
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers
)
Begin {
if ($CisServer.IsConnected) {
Write-Verbose "Connected to $($CisServer.Name)"
$connection = $CisServer
} elseif ($CisServer.gettype().name -eq "String") {
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
$Connection = Connect-CisServer $CisServer
} elseif ($global:DefaultCisServers) {
$connection = $global:DefaultCisServers
} elseif ($global:DefaultVIServer) {
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
$Connection = Connect-CisServer $global:DefaultVIServer
}
if (!$Connection) {
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
}
}
Process{
if (!(Test-VCSAScheduleSupport)) {
Write-Error "This VCSA does not support Backup Schedules."
return
}
if ($PSCmdlet.ShouldProcess($ScheduleID, "Removes Current Backup Schedule")) {
$BackupAPI = Get-CisService -name 'com.vmware.appliance.recovery.backup.schedules'
$BackupAPI.delete($ScheduleID)
}
}
End {}
}
Function Test-VCSAScheduleSupport {
<#
.NOTES
===========================================================================
Original Created by: Brian Graf
Blog: www.vtagion.com
Twitter: @vBrianGraf
Organization: VMware
Created / Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.SYNOPSIS
This function will check to see if your VCSA supports Scheduled Backups.
(vSphere 6.7 and higher)
.DESCRIPTION
Use this function to check if your VCSA supports Scheduled Backups.
.EXAMPLE
PS C:\> Test-VCSAScheduleSupport
.EXAMPLE
PS C:\> Test-VCSAScheduleSupport -CisServer "vcserver.sphere.local"
.NOTES
Credit goes to @AlanRenouf & @vBrianGraf for sharing the base of this function.
You must be connected to the CisService for this to work, if you are not connected, the function will prompt you for your credentia
#>
param (
[Parameter(Mandatory=$false)]$CisServer = $global:DefaultCisServers
)
Begin {
if ($CisServer.IsConnected) {
Write-Verbose "Connected to $($CisServer.Name)"
$connection = $CisServer
} elseif ($CisServer.gettype().name -eq "String") {
Write-Host "Prompting for CIS Server credentials. Connecting to $($CisServer)."
$Connection = Connect-CisServer $CisServer
} elseif ($global:DefaultCisServers) {
$connection = $global:DefaultCisServers
} elseif ($global:DefaultVIServer) {
Write-Host "Prompting for CIS Server credentials. Connecting to $($global:DefaultVIServer.name)."
$Connection = Connect-CisServer $global:DefaultVIServer
}
if (!$Connection) {
Write-Error "It appears you have not created a connection to the CisServer. Please Connect First and try command again. (Connect-CisServer)"
}
}
Process{
if ((Get-CisService).name -contains "com.vmware.appliance.recovery.backup.schedules" ) {
Write-Verbose "This VCSA does supports Backup Schedules."
return $true
} else {
Write-Verbose "This VCSA does not support Backup Schedules."
return $false
}
}
End {}
}

View File

@@ -1,4 +1,4 @@
Function Get-VAMISummary {
Function Get-VAMISummary {
<#
.NOTES
===========================================================================
@@ -17,7 +17,7 @@
Get-VAMISummary
#>
$systemVersionAPI = Get-CisService -Name 'com.vmware.appliance.system.version'
$results = $systemVersionAPI.get() | select product, type, version, build, install_time
$results = $systemVersionAPI.get() | select product, type, version, build, install_time, releasedate
$systemUptimeAPI = Get-CisService -Name 'com.vmware.appliance.system.uptime'
$ts = [timespan]::fromseconds($systemUptimeAPI.get().toString())
@@ -29,6 +29,7 @@
Version = $results.version;
Build = $results.build;
InstallTime = $results.install_time;
ReleaseDate = $results.releasedate;
Uptime = $uptime
}
$summaryResult
@@ -109,6 +110,7 @@ Function Get-VAMIAccess {
Console = $consoleAccess;
DCUI = $dcuiAccess;
BashShell = $shellAccess.enabled;
BashTimeout = $shellAccess.timeout;
SSH = $sshAccess
}
$accessResult
@@ -122,7 +124,10 @@ Function Get-VAMITime {
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 16, 2020
===========================================================================
.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.
@@ -131,12 +136,16 @@ Function Get-VAMITime {
.EXAMPLE
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
Get-VAMITime
.NOTES
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs
#>
$systemTimeAPI = Get-CisService -Name 'com.vmware.appliance.system.time'
$systemTimeAPI = ( Get-VAMIServiceAPI -NameFilter "system.time")
$timeResults = $systemTimeAPI.get()
$timeSync = (Get-CisService -Name 'com.vmware.appliance.techpreview.timesync').get()
$timeSyncMode = $timeSync.mode
$timeSyncMode = ( Get-VAMIServiceAPI -NameFilter "timesync").get()
if ($timeSyncMode.mode) {
$timeSyncMode = $timeSync.mode
}
$timeResult = [pscustomobject] @{
Timezone = $timeResults.timezone;
@@ -148,13 +157,84 @@ Function Get-VAMITime {
}
if($timeSyncMode -eq "NTP") {
$ntpServers = (Get-CisService -Name 'com.vmware.appliance.techpreview.ntp').get()
$timeResult.NTPServers = $ntpServers.servers
$timeResult.NTPStatus = $ntpServers.status
$ntpServers = ( Get-VAMIServiceAPI -NameFilter "ntp").get()
if ($ntpServers.servers) {
$timeResult.NTPServers = $ntpServers.servers
$timeResult.NTPStatus = $ntpServers.status
} else {
$timeResult.NTPServers = $ntpServers
$timeResult.NTPStatus = ( Get-VAMIServiceAPI -NameFilter "ntp").test(( Get-VAMIServiceAPI -NameFilter "ntp").get()).status
}
}
$timeResult
}
Function Set-VAMITimeSync {
<#
.NOTES
===========================================================================
Inspired by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
Created by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.SYNOPSIS
This function sets 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!
Set-VAMITimeSync -SyncMode "NTP" -TimeZone "US/Pacific" -NTPServers "10.0.0.10,10.0.0.11,10.0.0.12"
.NOTES
Create script to Set NTP for Newer VCSA. Script supports 6.7 VCSAs
#>
param(
[Parameter(Mandatory=$true)]
[ValidateSet('Disabled', 'NTP', 'Host')]
[String]$SyncMode,
[Parameter(Mandatory=$False,HelpMessage="TimeZone Name needs to be in Posix Naming / Unix format")]
[String]$TimeZone,
[Parameter(Mandatory=$false,HelpMessage="NTP Servers need to be either a string separated by ',' or an array of servers")]
$NTPServers
)
$timeSyncMode = ( Get-VAMIServiceAPI -NameFilter "timesync").get()
if ($timeSyncMode.gettype().name -eq "PSCustomObject") {
if ($SyncMode.ToUpper() -ne $timeSyncMode.mode.toupper()) {
$timesyncapi = (Get-VAMIServiceAPI -NameFilter "timesync")
$timesyncconfig = $timesyncapi.help.set.config.createexample()
$timesyncconfig = $Sync
$timesyncapi.set($timesyncconfig)
}
} else {
if ($SyncMode.ToUpper() -ne $timeSyncMode.toupper()) {
$timesyncapi = (Get-VAMIServiceAPI -NameFilter "timesync")
$timesyncapi.set($Sync)
}
if ($NTPServers) {
$ntpapi = (Get-VAMIServiceAPI -NameFilter "ntp")
if ($NTPServers.gettype().Name -eq "String") {
$NTPServersArray = ($NTPServers -split ",").trim()
} else {
$NTPServersArray = $NTPServers
}
if ($NTPServersArray -ne $ntpapi.get()) {
$ntpapi.set($NTPServersArray)
}
}
if ($TimeZone) {
$timezoneapi = (Get-VAMIServiceAPI -NameFilter "timezone")
if ($TimeZone -ne ($timezoneapi.get())) {
$timezoneapi.set($TimeZone)
}
}
}
}
Function Get-VAMINetwork {
<#
.NOTES
@@ -163,6 +243,9 @@ Function Get-VAMINetwork {
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.SYNOPSIS
This function retrieves network information from VAMI interface (5480)
@@ -172,22 +255,27 @@ Function Get-VAMINetwork {
.EXAMPLE
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
Get-VAMINetwork
.NOTES
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs
#>
$netResults = @()
$Hostname = (Get-CisService -Name 'com.vmware.appliance.networking.dns.hostname').get()
$dns = (Get-CisService -Name 'com.vmware.appliance.networking.dns.servers').get()
$Hostname = ( Get-VAMIServiceAPI -NameFilter "dns.hostname").get()
$dns = (Get-VAMIServiceAPI -NameFilter "dns.servers").get()
Write-Host "Hostname: " $hostname
Write-Host "DNS Servers: " $dns.servers
$interfaces = (Get-CisService -Name 'com.vmware.appliance.networking.interfaces').list()
$interfaces = (Get-VAMIServiceAPI -NameFilter "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)
$ipv4API = (Get-VAMIServiceAPI -NameFilter "ipv4")
if ($ipv4API.help.get.psobject.properties.name -like "*_*") {
$ipv4result = $ipv4API.get($interface.Name)
$Updateable = $ipv4result.configurable
} else {
$ipv4result = $ipv4API.get(@($interface.Name))
$Updateable = $ipv4result.updateable
}
$interfaceResult = [pscustomobject] @{
Inteface = $interface.name;
MAC = $interface.mac;
@@ -196,7 +284,7 @@ Function Get-VAMINetwork {
IP = $ipv4result.address;
Prefix = $ipv4result.prefix;
Gateway = $ipv4result.default_gateway;
Updateable = $ipv4result.updateable
Updateable = $Updateable
}
$netResults += $interfaceResult
}
@@ -286,6 +374,9 @@ Function Get-VAMIStorageUsed {
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 16, 2020
===========================================================================
.SYNOPSIS
This function retrieves the individaul OS partition storage utilization
@@ -295,70 +386,49 @@ Function Get-VAMIStorageUsed {
.EXAMPLE
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
Get-VAMIStorageUsed
.NOTES
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs.
Also modifed the static list of filesystems to be more dynamic in nature to account for the differences in VCSA versions.
#>
$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"
)
$querySpec.Names = ($monitoringAPI.list() | Where-Object {($_.name -like "*storage.used.filesystem*") -or ($_.name -like "*storage.totalsize.filesystem*") } | Select-Object id | Sort-Object -Property id).id.value
# Tuple (Filesystem Name, Used, Total) to store results
$storageStats = @{
"archive"=@{"name"="/storage/archive";"used"=0;"total"=0};
"autodeploy"=@{"name"="/storage/autodeploy";"used"=0;"total"=0};
"boot"=@{"name"="/boot";"used"=0;"total"=0};
"coredump"=@{"name"="/storage/core";"used"=0;"total"=0};
"core"=@{"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}
"db"=@{"name"="/storage/db";"used"=0;"total"=0};
"seat"=@{"name"="/storage/seat";"used"=0;"total"=0};
"dblog"=@{"name"="/storage/dblog";"used"=0;"total"=0};
"swap"=@{"name"="swap";"used"=0;"total"=0}
}
$querySpec.interval = "DAY1"
$querySpec.function = "MAX"
$querySpec.start_time = ((get-date).AddDays(-1))
$querySpec.start_time = ((Get-Date).AddDays(-1))
$querySpec.end_time = (Get-Date)
$queryResults = $monitoringAPI.query($querySpec) | Select * -ExcludeProperty Help
$queryResults = $monitoringAPI.query($querySpec) | Select-Object * -ExcludeProperty Help
foreach ($queryResult in $queryResults) {
# Update hash if its used storage results
$key = ((($queryResult.name).toString()).split(".")[-1]) -replace "coredump","core" -replace "vcdb_","" -replace "core_inventory","db" -replace "transaction_log","dblog"
$value = [Math]::Round([int]($queryResult.data[1]).toString()/1MB,2)
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
}
}
@@ -406,7 +476,6 @@ Function Get-VAMIService {
if($Name -ne "") {
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
try {
$serviceStatus = $vMonAPI.get($name,0)
$serviceString = [pscustomobject] @{
@@ -423,7 +492,6 @@ Function Get-VAMIService {
} 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] @{
@@ -448,7 +516,7 @@ Function Start-VAMIService {
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.
@@ -470,8 +538,8 @@ Function Start-VAMIService {
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
try {
Write-Host "Starting $name service ..."
$vMonAPI.start($name)
Write-Host "Starting $Name service ..."
$vMonAPI.start($Name)
} catch {
Write-Error $Error[0].exception.Message
}
@@ -507,8 +575,8 @@ Function Stop-VAMIService {
$vMonAPI = Get-CisService 'com.vmware.appliance.vmon.service'
try {
Write-Host "Stopping $name service ..."
$vMonAPI.stop($name)
Write-Host "Stopping $Name service ..."
$vMonAPI.stop($Name)
} catch {
Write-Error $Error[0].exception.Message
}
@@ -556,15 +624,20 @@ Function Get-VAMIUser {
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
This function retrieves VAMI local users using VAMI interface (5480)
Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 16, 2020
===========================================================================
.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
.DESCRIPTION
Function to retrieve VAMI local users
.EXAMPLE
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
Get-VAMIUser
.NOTES
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs.
#>
param(
[Parameter(
@@ -575,42 +648,47 @@ Function Get-VAMIUser {
[String]$Name
)
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
$userAPI = Get-VAMIServiceAPI -NameFilter "accounts"
$UserResults = @()
$userResults = @()
if($Name -ne "") {
if (($Name -ne "") -and ($null -ne $Name)) {
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
$Users = $UserAPI.get($name)
} 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
$Users = $UserAPI.list()
}
if ($Users.status) {
foreach ($User in $Users) {
$UserString = [pscustomobject] @{
User = $User.username
Name = $User.fullname
Email = $User.email
Status = $User.status
PasswordStatus = $User.passwordstatus
Roles = @($User.role)
}
$userResults += $userString
$UserResults += $UserString
}
} else {
foreach ($User in $Users) {
$UserInfo = $userAPI.get($user)
$UserString = [pscustomobject] @{
User = $User.value
Name = $UserInfo.fullname
Email = $UserInfo.email
Status = $UserInfo.enabled
LastPasswordChange = $UserInfo.last_password_change
PasswordExpiresAt = $UserInfo.password_expires_at
PasswordStatus = if ($UserInfo.has_password) { if ((!!$UserInfo.password_expires_at) -and ([datetime]$UserInfo.password_expires_at -lt (get-date))) {"good"} else {"expired"}} else { "notset"}
Roles = $UserInfo.roles
}
$UserResults += $UserString
}
}
$userResults
$UserResults
}
Function New-VAMIUser {
@@ -621,53 +699,144 @@ Function New-VAMIUser {
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
This function to create new VAMI local user using VAMI interface (5480)
Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 16, 2020
===========================================================================
.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
.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!"
New-VAMIUser -name lamw -fullname "William Lam" -role "operator" -email "lamw@virtuallyghetto.com" -password "VMware1!" -passwordexpires -passwordexpiresat "1/1/1970" -maxpasswordage 90
.NOTES
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs.
Also added new Parameters to script.
#>
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
[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,
[Parameter(Mandatory=$false)]
[switch]$PasswordExpires,
[Parameter(Mandatory=$false)]
[String]$PasswordExpiresAt = $null,
[Parameter(Mandatory=$false)]
[String]$MaxPasswordAge = 90
)
$userAPI = Get-CisService 'com.vmware.appliance.techpreview.localaccounts.user'
$createSpec = $userAPI.Help.add.config.CreateExample()
$userAPI = Get-VAMIServiceAPI -NameFilter "accounts"
if ($userAPI.name -eq 'com.vmware.appliance.techpreview.localaccounts.user') {
$CreateSpec = $UserAPI.Help.add.config.CreateExample()
} else {
$CreateSpec = $UserAPI.Help.create.config.CreateExample()
}
$createSpec.username = $name
$createSpec.fullname = $fullname
$createSpec.role = $role
$createSpec.email = $email
$createSpec.password = [VMware.VimAutomation.Cis.Core.Types.V1.Secret]$password
$CreateSpec.fullname = $FullName
$CreateSpec.role = $Role
$CreateSpec.email = $Email
$CreateSpec.password = [VMware.VimAutomation.Cis.Core.Types.V1.Secret]$Password
if ($CreateSpec.psobject.properties.name -contains "username") {
$CreateSpec.username = $Name
try {
Write-Host "Creating new user $Name ..."
$UserAPI.add($CreateSpec)
} catch {
Write-Error $Error[0].exception.Message
}
} else {
$CreateSpec.password_expires = $PasswordExpires
$CreateSpec.password_expires_at = $PasswordExpiresAt
$CreateSpec.max_days_between_password_change = $MaxPasswordAge
try {
Write-Host "Creating new user $Name ..."
$UserAPI.create($Name, $CreateSpec)
} catch {
Write-Error $Error[0].exception.Message
}
}
}
try {
Write-Host "Creating new user $name ..."
$userAPI.add($createSpec)
} catch {
Write-Error $Error[0].exception.Message
Function Update-VAMIUser {
<#
.NOTES
===========================================================================
Inspired by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
Created by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.SYNOPSIS
This function to update fields of a 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 update fields of a VAMI local user
.EXAMPLE
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
Update-VAMIUser -name lamw -fullname "William Lam" -role "operator" -email "lamw@virtuallyghetto.com" -password "VMware1!" -passwordexpires -passwordexpiresat "1/1/1970" -maxpasswordage 90
.NOTES
Created script to allow updating of an exisiting user account. Script supports 6.5 and 6.7 VCSAs.
#>
param(
[Parameter(Mandatory=$true)]
[String]$Name,
[Parameter(Mandatory=$false)]
[String]$FullName,
[Parameter(Mandatory=$false)]
[ValidateSet("admin","operator","superAdmin")]
[String]$Role,
[Parameter(Mandatory=$false)]
[String]$Email="",
[Parameter(Mandatory=$false)]
[String]$Password = $null,
[Parameter(Mandatory=$false)]
[switch]$PasswordExpires,
[Parameter(Mandatory=$false)]
[String]$PasswordExpiresAt = $null,
[Parameter(Mandatory=$false)]
[String]$MaxPasswordAge = 90
)
$userAPI = Get-VAMIServiceAPI -NameFilter "accounts"
$UpdateSpec = $UserAPI.Help.set.config.CreateExample()
$UpdateSpec.fullname = $FullName
$UpdateSpec.role = $Role
$UpdateSpec.email = $Email
if ($UpdateSpec.psobject.properties.name -contains "username") {
$UpdateSpec.username = $Name
try {
Write-Host "Updating Settings for user $Name ..."
$UserAPI.set($UpdateSpec)
} catch {
Write-Error $Error[0].exception.Message
}
} else {
$UpdateSpec.password = [VMware.VimAutomation.Cis.Core.Types.V1.Secret]$Password
$UpdateSpec.password_expires = $PasswordExpires
$UpdateSpec.password_expires_at = $PasswordExpiresAt
$UpdateSpec.max_days_between_password_change = $MaxPasswordAge
try {
Write-Host "Updating Settings for user $Name ..."
$UserAPI.update($Name, $UpdateSpec)
} catch {
Write-Error $Error[0].exception.Message
}
}
}
@@ -679,32 +848,30 @@ Function Remove-VAMIUser {
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
This function to remove VAMI local user using VAMI interface (5480)
Modifed by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.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
.DESCRIPTION
Function to remove VAMI local user
.EXAMPLE
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
Get-VAMIAccess
.NOTES
Modified script to account for Newer VCSA. Script supports 6.5 and 6.7 VCSAs.
#>
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = 'High')]
param(
[Parameter(
Mandatory=$true)
]
[String]$name,
[Parameter(
Mandatory=$false)
]
[boolean]$confirm=$false
[Parameter(Mandatory=$true)]
[String]$Name
)
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'
Begin {}
Process{
if($PSCmdlet.ShouldProcess($Name,'Delete')) {
$userAPI = Get-VAMIServiceAPI -NameFilter "accounts"
try {
Write-Host "Deleting user $name ..."
$userAPI.delete($name)
@@ -713,4 +880,41 @@ Function Remove-VAMIUser {
}
}
}
}
End{}
}
Function Get-VAMIServiceAPI {
<#
.NOTES
===========================================================================
Inspired by: William Lam
Organization: VMware
Blog: www.virtuallyghetto.com
Twitter: @lamw
Created by: Michael Dunsdon
Twitter: @MJDunsdon
Date: September 21, 2020
===========================================================================
.SYNOPSIS
This function returns the Service Api Based on a String of Service Name.
.DESCRIPTION
Function to find and get service api based on service name string
.EXAMPLE
Connect-CisServer -Server 192.168.1.51 -User administrator@vsphere.local -Password VMware1!
Get-VAMIUser -NameFilter "accounts"
.NOTES
Script supports 6.5 and 6.7 VCSAs.
Function Gets all Service Api Names and filters the list based on NameFilter
If Multiple Serivces are returned it takes the Top one.
#>
param(
[Parameter(Mandatory=$true)]
[String]$NameFilter
)
$ServiceAPI = Get-CisService | Where-Object {$_.name -like "*$($NameFilter)*"}
if (($ServiceAPI.count -gt 1) -and $NameFilter) {
$ServiceAPI = ($ServiceAPI | Sort-Object -Property Name)[0]
}
return $ServiceAPI
}

View File

@@ -83,7 +83,7 @@ Function Get-NSXTSegment {
If (-Not $global:nsxtProxyConnection) { Write-error "No NSX-T Proxy Connection found, please use Connect-NSXTProxy" } Else {
$method = "GET"
$segmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-1s/cgw/segments"
$segmentsURL = $global:nsxtProxyConnection.Server + "/policy/api/v1/infra/tier-1s/cgw/segments?page_size=100"
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] - $METHOD`n$segmentsURL`n"
@@ -108,14 +108,53 @@ Function Get-NSXTSegment {
}
if($requests.StatusCode -eq 200) {
$segments = ($requests.Content | ConvertFrom-Json).results
$baseSegmentsURL = $segmentsURL
$totalSegmentCount = ($requests.Content | ConvertFrom-Json).result_count
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] totalSegmentCount = $totalSegmentCount"
}
$totalSegments = ($requests.Content | ConvertFrom-Json).results
$seenSegments = $totalSegments.count
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] $segmentsURL (currentCount = $seenSegments)"
}
while ( $seenSegments -lt $totalSegmentCount) {
$segmentsURL = $baseSegmentsURL + "&cursor=$(($requests.Content | ConvertFrom-Json).cursor)"
try {
if($PSVersionTable.PSEdition -eq "Core") {
$requests = Invoke-WebRequest -Uri $segmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers -SkipCertificateCheck
} else {
$requests = Invoke-WebRequest -Uri $segmentsURL -Method $method -Headers $global:nsxtProxyConnection.headers
}
} catch {
if($_.Exception.Response.StatusCode -eq "Unauthorized") {
Write-Host -ForegroundColor Red "`nThe NSX-T Proxy session is no longer valid, please re-run the Connect-NSXTProxy cmdlet to retrieve a new token`n"
break
} else {
Write-Error "Error in retrieving NSX-T Segments"
Write-Error "`n($_.Exception.Message)`n"
break
}
}
$segments = ($requests.Content | ConvertFrom-Json).results
$totalSegments += $segments
$seenSegments += $segments.count
if($Troubleshoot) {
Write-Host -ForegroundColor cyan "`n[DEBUG] $segmentsURL (currentCount = $seenSegments)"
}
}
if ($PSBoundParameters.ContainsKey("Name")){
$segments = $segments | where {$_.display_name -eq $Name}
$totalSegments = $totalSegments | where {$_.display_name -eq $Name}
}
$results = @()
foreach ($segment in $segments) {
foreach ($segment in $totalSegments) {
$subnets = $segment.subnets
$network = $subnets.network

View File

@@ -0,0 +1,90 @@
#
# Module manifest for module 'VMware.WorkloadManagement'
#
# Generated by: wlam@vmware.com
#
# Generated on: 05/19/20
#
@{
# Script module or binary module file associated with this manifest.
RootModule = 'VMware.WorkloadManagement.psm1'
# Version number of this module.
ModuleVersion = '1.0.0'
# Supported PSEditions
# CompatiblePSEditions = @()
# ID used to uniquely identify this module
GUID = 'VMware.WorkloadManagement'
# Author of this module
Author = 'William Lam'
# Company or vendor of this module
CompanyName = 'VMware'
# Copyright statement for this module
Copyright = '(c) 2020 VMware. All rights reserved.'
# Description of the functionality provided by this module
Description = 'PowerShell Module for vSphere with Kubernetes Workload Management'
# Minimum version of the Windows PowerShell engine required by this module
PowerShellVersion = '6.0'
# Functions to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no functions to export.
FunctionsToExport = 'New-WorkloadManagement','Get-WorkloadManagement','Remove-WorkloadManagement'
# Cmdlets to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no cmdlets to export.
CmdletsToExport = @()
# Variables to export from this module
VariablesToExport = '*'
# Aliases to export from this module, for best performance, do not use wildcards and do not delete the entry, use an empty array if there are no aliases to export.
AliasesToExport = @()
# DSC resources to export from this module
# DscResourcesToExport = @()
# List of all modules packaged with this module
# ModuleList = @()
# List of all files packaged with this module
# FileList = @()
# Private data to pass to the module specified in RootModule/ModuleToProcess. This may also contain a PSData hashtable with additional module metadata used by PowerShell.
PrivateData = @{
PSData = @{
# Tags applied to this module. These help with module discovery in online galleries.
# Tags = @()
# A URL to the license for this module.
# LicenseUri = ''
# A URL to the main website for this project.
# ProjectUri = ''
# A URL to an icon representing this module.
# IconUri = ''
# ReleaseNotes of this module
# ReleaseNotes = ''
} # End of PSData hashtable
} # End of PrivateData hashtable
# HelpInfo URI of this module
# HelpInfoURI = ''
# Default prefix for commands exported from this module. Override the default prefix using Import-Module -Prefix.
# DefaultCommandPrefix = ''
}

View File

@@ -0,0 +1,356 @@
Function New-WorkloadManagement {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 05/19/2020
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Enable Workload Management on vSphere 7 Cluster
.DESCRIPTION
Enable Workload Management on vSphere 7 Cluster
.PARAMETER ClusterName
Name of vSphere Cluster to enable Workload Management
.PARAMETER ControlPlaneSize
Size of Control Plane VMs (TINY, SMALL, MEDIUM, LARGE)
.PARAMETER MgmtNetwork
Management Network for Control Plane VMs
.PARAMETER MgmtNetworkStartIP
Starting IP Address for Control Plane VMs (5 consecutive free addresses)
.PARAMETER MgmtNetworkSubnet
Netmask for Management Network
.PARAMETER MgmtNetworkGateway
Gateway for Management Network
.PARAMETER MgmtNetworkDNS
DNS Server(s) to use for Management Network
.PARAMETER MgmtNetworkDNSDomain
DNS Domain(s)
.PARAMETER MgmtNetworkNTP
NTP Server(s)
.PARAMETER WorkloadNetworkVDS
Name of vSphere 7 Distributed Virtual Switch (VDS) configured with NSX-T
.PARAMETER WorkloadNetworkEdgeCluster
Name of NSX-T Edge Cluster
.PARAMETER WorkloadNetworkDNS
DNS Server(s) to use for Workloads
.PARAMETER WorkloadNetworkPodCIDR
K8s POD CIDR (default: 10.244.0.0/21)
.PARAMETER WorkloadNetworkServiceCIDR
K8S Service CIDR (default: 10.96.0.0/24)
.PARAMETER WorkloadNetworkIngressCIDR
CIDR for Workload Ingress (recommend /27 or larger)
.PARAMETER WorkloadNetworkEgressCIDR
CIDR for Workload Egress (recommend /27 or larger)
.PARAMETER ControlPlaneStoragePolicy
Name of VM Storage Policy to use for Control Plane VMs
.PARAMETER EphemeralDiskStoragePolicy
Name of VM Storage Policy to use for Ephemeral Disk
.PARAMETER ImageCacheStoragePolicy
Name of VM Storage Policy to use for Image Cache
.PARAMETER LoginBanner
Login message to show during kubectl login
.EXAMPLE
New-WorkloadManagement `
-ClusterName "Workload-Cluster" `
-ControlPlaneSize TINY `
-MgmtNetwork "DVPG-Management Network" `
-MgmtNetworkStartIP "172.17.36.51" `
-MgmtNetworkSubnet "255.255.255.0" `
-MgmtNetworkGateway "172.17.36.253" `
-MgmtNetworkDNS "172.17.31.5" `
-MgmtNetworkDNSDomain "cpub.corp" `
-MgmtNetworkNTP "5.199.135.170" `
-WorkloadNetworkVDS "Pacific-VDS" `
-WorkloadNetworkEdgeCluster "Edge-Cluster-01" `
-WorkloadNetworkDNS "172.17.31.5" `
-WorkloadNetworkIngressCIDR "172.17.36.64/27" `
-WorkloadNetworkEgressCIDR "172.17.36.96/27" `
-ControlPlaneStoragePolicy "pacific-gold-storage-policy" `
-EphemeralDiskStoragePolicy "pacific-gold-storage-policy" `
-ImageCacheStoragePolicy "pacific-gold-storage-policy"
#>
Param (
[Parameter(Mandatory=$True)]$ClusterName,
[Parameter(Mandatory=$True)][ValidateSet("TINY","SMALL","MEDIUM","LARGE")][string]$ControlPlaneSize,
[Parameter(Mandatory=$True)]$MgmtNetwork,
[Parameter(Mandatory=$True)]$MgmtNetworkStartIP,
[Parameter(Mandatory=$True)]$MgmtNetworkSubnet,
[Parameter(Mandatory=$True)]$MgmtNetworkGateway,
[Parameter(Mandatory=$True)][string[]]$MgmtNetworkDNS,
[Parameter(Mandatory=$True)][string[]]$MgmtNetworkDNSDomain,
[Parameter(Mandatory=$True)]$MgmtNetworkNTP,
[Parameter(Mandatory=$True)]$WorkloadNetworkVDS,
[Parameter(Mandatory=$True)]$WorkloadNetworkEdgeCluster,
[Parameter(Mandatory=$True)][string[]]$WorkloadNetworkDNS,
[Parameter(Mandatory=$False)]$WorkloadNetworkPodCIDR="10.244.0.0/21",
[Parameter(Mandatory=$False)]$WorkloadNetworkServiceCIDR="10.96.0.0/24",
[Parameter(Mandatory=$True)]$WorkloadNetworkIngressCIDR,
[Parameter(Mandatory=$True)]$WorkloadNetworkEgressCIDR,
[Parameter(Mandatory=$True)]$ControlPlaneStoragePolicy,
[Parameter(Mandatory=$True)]$EphemeralDiskStoragePolicy,
[Parameter(Mandatory=$True)]$ImageCacheStoragePolicy,
[Parameter(Mandatory=$False)]$LoginBanner
)
If (-Not $global:DefaultCisServers) { Write-error "No CiS Connection found, please use Connect-CisServer`n" } Else {
# Management Network Moref
$networkService = Get-CisService "com.vmware.vcenter.network"
$networkFilterSpec = $networkService.help.list.filter.Create()
$networkFilterSpec.names = @("$MgmtNetwork")
$mgmtNetworkMoRef = $networkService.list($networkFilterSpec).network.Value
if ($mgmtNetworkMoRef -eq $NULL) {
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster ${MgmtNetwork}"
break
}
# Cluster Moref
$clusterService = Get-CisService "com.vmware.vcenter.cluster"
$clusterFilterSpec = $clusterService.help.list.filter.Create()
$clusterFilterSpec.names = @("$ClusterName")
$clusterMoRef = $clusterService.list($clusterFilterSpec).cluster.Value
if ($clusterMoRef -eq $NULL) {
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster ${ClusterName}"
break
}
# VDS MoRef
$vdsCompatService = Get-CisService "com.vmware.vcenter.namespace_management.distributed_switch_compatibility"
$vdsMoRef = ($vdsCompatService.list($clusterMoref)).distributed_switch.Value
if ($vdsMoRef -eq $NULL) {
Write-Host -ForegroundColor Red "Unable to find VDS ${WorkloadNetworkVDS}"
break
}
# NSX-T Edge Cluster
$edgeClusterService = Get-CisService "com.vmware.vcenter.namespace_management.edge_cluster_compatibility"
$edgeClusterMoRef = ($edgeClusterService.list($clusterMoref,$vdsMoRef)).edge_cluster.Value
if ($edgeClusterMoRef -eq $NULL) {
Write-Host -ForegroundColor Red "Unable to find NSX-T Edge Cluster ${WorkloadNetworkEdgeCluster}"
break
}
# VM Storage Policy MoRef
$storagePolicyService = Get-CisService "com.vmware.vcenter.storage.policies"
$sps= $storagePolicyService.list()
$cpSP = ($sps | where {$_.name -eq $ControlPlaneStoragePolicy}).Policy.Value
$edSP = ($sps | where {$_.name -eq $EphemeralDiskStoragePolicy}).Policy.Value
$icSP = ($sps | where {$_.name -eq $ImageCacheStoragePolicy}).Policy.Value
if ($cpSP -eq $NULL) {
Write-Host -ForegroundColor Red "Unable to find VM Storage Policy ${ControlPlaneStoragePolicy}"
break
}
if ($edSP -eq $NULL) {
Write-Host -ForegroundColor Red "Unable to find VM Storage Policy ${EphemeralDiskStoragePolicy}"
break
}
if ($icSP -eq $NULL) {
Write-Host -ForegroundColor Red "Unable to find VM Storage Policy ${ImageCacheStoragePolicy}"
break
}
$nsmClusterService = Get-CisService "com.vmware.vcenter.namespace_management.clusters"
$spec = $nsmClusterService.help.enable.spec.Create()
$spec.size_hint = $ControlPlaneSize
$spec.network_provider = "NSXT_CONTAINER_PLUGIN"
$mgmtNetworkSpec = $nsmClusterService.help.enable.spec.master_management_network.Create()
$mgmtNetworkSpec.mode = "STATICRANGE"
$mgmtNetworkSpec.network = $mgmtNetworkMoRef
$mgmtNetworkSpec.address_range.starting_address = $MgmtNetworkStartIP
$mgmtNetworkSpec.address_range.address_count = 5
$mgmtNetworkSpec.address_range.subnet_mask = $MgmtNetworkSubnet
$mgmtNetworkSpec.address_range.gateway = $MgmtNetworkGateway
$spec.master_management_network = $mgmtNetworkSpec
$spec.master_DNS = $MgmtNetworkDNS
$spec.master_DNS_search_domains = $MgmtNetworkDNSDomain
$spec.master_NTP_servers = $MgmtNetworkNTP
$spec.ncp_cluster_network_spec.cluster_distributed_switch = $vdsMoRef
$spec.ncp_cluster_network_spec.nsx_edge_cluster = $edgeClusterMoRef
$spec.worker_DNS = $WorkloadNetworkDNS
$serviceCidrSpec = $nsmClusterService.help.enable.spec.service_cidr.Create()
$serviceAddress,$servicePrefix = $WorkloadNetworkServiceCIDR.split("/")
$serviceCidrSpec.address = $serviceAddress
$serviceCidrSpec.prefix = $servicePrefix
$spec.service_cidr = $serviceCidrSpec
$podCidrSpec = $nsmClusterService.help.enable.spec.ncp_cluster_network_spec.pod_cidrs.Element.Create()
$podAddress,$podPrefix = $WorkloadNetworkPodCIDR.split("/")
$podCidrSpec.address = $podAddress
$podCidrSpec.prefix = $podPrefix
$spec.ncp_cluster_network_spec.pod_cidrs = @($podCidrSpec)
$egressCidrSpec = $nsmClusterService.help.enable.spec.ncp_cluster_network_spec.egress_cidrs.Element.Create()
$egressAddress,$egressPrefix = $WorkloadNetworkEgressCIDR.split("/")
$egressCidrSpec.address = $egressAddress
$egressCidrSpec.prefix = $egressPrefix
$spec.ncp_cluster_network_spec.egress_cidrs = @($egressCidrSpec)
$ingressCidrSpec = $nsmClusterService.help.enable.spec.ncp_cluster_network_spec.ingress_cidrs.Element.Create()
$ingressAddress,$ingressPrefix = $WorkloadNetworkIngressCIDR.split("/")
$ingressCidrSpec.address = $ingressAddress
$ingressCidrSpec.prefix = $ingressPrefix
$spec.ncp_cluster_network_spec.ingress_cidrs = @($ingressCidrSpec)
$spec.master_storage_policy = $cpSP
$spec.ephemeral_storage_policy = $edSP
$imagePolicySpec = $nsmClusterService.help.enable.spec.image_storage.Create()
$imagePolicySpec.storage_policy = $icSP
$spec.image_storage = $imagePolicySpec
if($LoginBanner -eq $NULL) {
$LoginBanner = "
" + [char]::ConvertFromUtf32(0x1F973) + "vSphere with Kubernetes Cluster enabled by virtuallyGhetto " + [char]::ConvertFromUtf32(0x1F973) + "
"
}
$spec.login_banner = $LoginBanner
try {
Write-Host -Foreground Green "`nEnabling Workload Management on vSphere Cluster ${ClusterName} ..."
$nsmClusterService.enable($clusterMoRef,$spec)
} catch {
Write-Error "Error in attempting to enable Workload Management on vSphere Cluster ${ClusterName}"
Write-Error "`n($_.Exception.Message)`n"
break
}
Write-Host -Foreground Green "Please refer to the Workload Management UI in vCenter Server to monitor the progress of this operation"
}
}
Function Get-WorkloadManagement {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 05/19/2020
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Retrieve all Workload Management Clusters
.DESCRIPTION
Retrieve all Workload Management Clusters
.PARAMETER Stats
Output additional stats pertaining to CPU, Memory and Storage
.EXAMPLE
Get-WorkloadManagement
.EXAMPLE
Get-WorkloadManagement -Stats
#>
Param (
[Switch]$Stats
)
If (-Not $global:DefaultCisServers) { Write-error "No CiS Connection found, please use Connect-CisServer`n" } Else {
If (-Not $global:DefaultVIServers) { Write-error "No VI Connection found, please use Connect-VIServer`n" } Else {
$nssClusterService = Get-CisService "com.vmware.vcenter.namespace_management.software.clusters"
$nsInstanceService = Get-CisService "com.vmware.vcenter.namespaces.instances"
$nsmClusterService = Get-CisService "com.vmware.vcenter.namespace_management.clusters"
$wlClusters = $nsmClusterService.list()
$results = @()
foreach ($wlCluster in $wlClusters) {
$workloadClusterId = $wlCluster.cluster
$vSphereCluster = Get-Cluster | where {$_.id -eq "ClusterComputeResource-${workloadClusterId}"}
$workloadCluster = $nsmClusterService.get($workloadClusterId)
$nsCount = ($nsInstanceService.list() | where {$_.cluster -eq $workloadClusterId}).count
$hostCount = ($vSphereCluster.ExtensionData.Host).count
if($workloadCluster.kubernetes_status -ne "ERROR") {
$k8sVersion = $nssClusterService.get($workloadClusterId).current_version
} else { $k8sVersion = "UNKNOWN" }
$tmp = [pscustomobject] @{
NAME = $vSphereCluster.name;
NAMESPACES = $nsCount;
HOSTS = $hostCount;
CONTROL_PLANE_IP = $workloadCluster.api_server_cluster_endpoint;
CLUSTER_STATUS = $workloadCluster.config_status;
K8S_STATUS = $workloadCluster.kubernetes_status;
VERSION = $k8sVersion;
}
if($Stats) {
$tmp | Add-Member -NotePropertyName CPU_CAPACITY -NotePropertyValue $workloadCluster.stat_summary.cpu_capacity
$tmp | Add-Member -NotePropertyName MEM_CAPACITY -NotePropertyValue $workloadCluster.stat_summary.memory_capacity
$tmp | Add-Member -NotePropertyName STORAGE_CAPACITY -NotePropertyValue $workloadCluster.stat_summary.storage_capacity
$tmp | Add-Member -NotePropertyName CPU_USED -NotePropertyValue $workloadCluster.stat_summary.cpu_used
$tmp | Add-Member -NotePropertyName MEM_USED -NotePropertyValue $workloadCluster.stat_summary.memory_used
$tmp | Add-Member -NotePropertyName STORAGE_USED -NotePropertyValue $workloadCluster.stat_summary.storage_used
}
$results+=$tmp
}
$results
}
}
}
Function Remove-WorkloadManagement {
<#
.NOTES
===========================================================================
Created by: William Lam
Date: 05/19/2020
Organization: VMware
Blog: http://www.virtuallyghetto.com
Twitter: @lamw
===========================================================================
.SYNOPSIS
Disable Workload Management on vSphere Cluster
.DESCRIPTION
Disable Workload Management on vSphere Cluster
.PARAMETER ClusterName
Name of vSphere Cluster to disable Workload Management
.EXAMPLE
Remove-WorkloadManagement -ClusterName "Workload-Cluster"
#>
Param (
[Parameter(Mandatory=$True)]$ClusterName
)
If (-Not $global:DefaultCisServers) { Write-error "No CiS Connection found, please use Connect-CisServer`n" } Else {
$vSphereCluster = Get-Cluster | where {$_.Name -eq $ClusterName}
if($vSphereCluster -eq $null) {
Write-Host -ForegroundColor Red "Unable to find vSphere Cluster ${ClusterName}"
break
}
$vSphereClusterID = ($vSphereCluster.id).replace("ClusterComputeResource-","")
$nsmClusterService = Get-CisService "com.vmware.vcenter.namespace_management.clusters"
$workloadClusterID = ($nsmClusterService.list() | where {$_.cluster -eq $vSphereClusterID}).cluster.Value
if($workloadClusterID -eq $null) {
Write-Host -ForegroundColor Red "Unable to find Workload Management Cluster ${ClusterName}"
break
}
try {
Write-Host -Foreground Green "`nDisabling Workload Management on vSphere Cluster ${ClusterName} ..."
$nsmClusterService.disable($workloadClusterID)
} catch {
Write-Error "Error in attempting to disable Workload Management on vSphere Cluster ${ClusterName}"
Write-Error "`n($_.Exception.Message)`n"
break
}
Write-Host -Foreground Green "Please refer to the Workload Management UI in vCenter Server to monitor the progress of this operation"
}
}

View File

@@ -0,0 +1,69 @@
#Requires -Modules Pester, VMware.VMC
inModuleScope VMware.VMC {
$functionName = "Connect-VMCVIServer"
Describe "$functionName" -Tag 'Unit' {
. "$PSScriptRoot/Shared.ps1"
$Org = 'MyOrg'
$Sddc = 'MySddc'
$global:DefaultVMCServers = $true
$secpasswd = ConvertTo-SecureString "password" -AsPlainText -Force
$Mockedcreds = New-Object System.Management.Automation.PSCredential ("username", $secpasswd)
$cloud_username = "MockedUserName"
$vc_public_ip = "MockedServer"
Mock Get-VMCSDDCDefaultCredential {
$object = [PSCustomObject] @{
'vc_public_ip' = $vc_public_ip
'cloud_username' = $cloud_username
'cloud_password' = $Mockedcreds.Password
}
return $object
}
Mock Write-host {}
Mock Connect-VIServer {}
Mock Connect-CisServer {}
Mock Write-Error
Context "Sanity checking" {
$command = Get-Command -Name $functionName
defParam $command 'Org'
defParam $command 'Sddc'
defParam $command 'Autologin'
}
Context "Behavior testing" {
It "gets creds via Get-VMCSDDCDefaultCredential" {
{ Connect-VMCVIServer -org $Org -Sddc $Sddc } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCSDDCDefaultCredential -Times 1 -Scope It -ParameterFilter { $org -eq $Org -and $Sddc -eq $Sddc }
}
It "calls the Connect-VIServer" {
{ Connect-VMCVIServer -org $Org -Sddc $Sddc } | Should Not Throw
Assert-MockCalled -CommandName Connect-VIServer -Times 1 -Scope It -ParameterFilter { `
$Server -eq $vc_public_ip `
-and $User -eq $cloud_username `
-and $Password -eq $Mockedcreds.Password }
}
It "calls the Connect-CisServer" {
{ Connect-VMCVIServer -org $Org -Sddc $Sddc } | Should Not Throw
Assert-MockCalled -CommandName Connect-CisServer -Times 1 -Scope It -ParameterFilter { `
$Server -eq $vc_public_ip `
-and $User -eq $cloud_username `
-and $Password -eq $Mockedcreds.password }
}
It "gets writes an error if not connected" {
$global:DefaultVMCServers = $false
{ Connect-VMCVIServer -org $Org -Sddc $Sddc } | Should Not Throw
Assert-MockCalled -CommandName Write-Error -Times 1 -Scope It -ParameterFilter { $org -eq $Org -and $Sddc -eq $Sddc }
}
}
}
}

View File

@@ -0,0 +1,23 @@
#Requires -Modules Pester, VMware.VMC, VMware.VimAutomation.Vmc
inModuleScope VMware.VMC {
$functionName = "Get-VMCCommand"
Describe "$functionName" -Tag 'Unit' {
Mock Get-Command {
"Mocked Command Response"
}
Context "Behavior testing" {
It "should call get-command on VMware.VimAutomation.Vmc" {
{ Get-VMCCommand } | Should Not Throw
Assert-MockCalled -CommandName Get-command -Times 1 -Scope It -ParameterFilter { $Module -eq 'VMware.VimAutomation.Vmc' }
}
It "should call get-command on VMware.Vmc" {
{ Get-VMCCommand } | Should Not Throw
Assert-MockCalled -CommandName Get-command -Times 1 -Scope It -ParameterFilter { $Module -eq 'VMware.VMC' }
}
}
}
}

View File

@@ -0,0 +1,75 @@
#Requires -Modules Pester, VMware.VMC
Import-Module -Name VMware.VimAutomation.Cis.Core
inModuleScope VMware.VMC {
$functionName = "Get-VMCFirewallRule"
Describe "$functionName" -Tag 'Unit' {
. "$PSScriptRoot/Shared.ps1"
$global:DefaultVMCServers = $true
$Service = "com.vmware.vmc.orgs.sddcs.networks.edges.firewall.config"
$OrgId = "Mocked OrgID"
$GatewayType = "MGW"
$SddcName = "MockedSDDCName"
$OrgName = "MockedOrgName"
$version = "MockedVersion"
$orgs = @(
[PSCustomObject]@{
"Id" = $OrgId
"Org_Id" = $OrgId
})
$MockedServiceObj = [PSCustomObject]{}
$ServicesObject = @([PSCustomObject]@{
"resource_config" = @{
sddc_manifest = [PSCustomObject]@{
version = $version
}
}
})
Mock -CommandName Get-VMCOrg -MockWith { $orgs }
Mock -CommandName Get-VMCSDDC -MockWith { $orgs }
Mock -CommandName Get-VMCService -MockWith { $MockedServiceObj }
$MockedServiceObj | Add-Member -MemberType ScriptMethod -Name "Get" -Value { $ServicesObject }
$MockedServiceObj | Add-Member -MemberType ScriptMethod -Name "list" -Value { $ServicesObject }
Mock -CommandName Write-Error -MockWith {}
Context "Sanity checking" {
$command = Get-Command -Name $functionName
defParam $command 'OrgName'
defParam $command 'SDDCName'
defParam $command 'ShowAll'
defParam $command 'GatewayType'
}
Context "Behavior testing" {
# Testing single Org with optional SDDC parameter
It "calls Get-VMCFirewallRule with the Org name supplied" {
{ Get-VMCFirewallRule -GatewayType $GatewayType -SDDCName $SddcName -OrgName $OrgName} | Should Not Throw
Assert-MockCalled -CommandName Get-VMCOrg -Times 1 -Scope It #-ParameterFilter { $Name -eq $SddcName }
Assert-MockCalled -CommandName Get-VMCSDDC -Times 1 -Scope It -ParameterFilter { $Name -eq $SddcName -and $Org -eq $OrgName }
}
It "calls get-service to com.vmware.vmc.orgs.sddcs" {
{ Get-VMCFirewallRule -GatewayType $GatewayType } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCService -Times 1 -Scope It -ParameterFilter { $name -eq $Service }
}
# Testing a single SDDC response
It "gets the task details via list method and returns the properties" {
$(Get-VMCFirewallRule -GatewayType $GatewayType).version | Should -be $version
}
It "writes an error if not connected" {
$global:DefaultVMCServers = $false
{ Get-VMCFirewallRule -GatewayType $GatewayType } | Should Not Throw
Assert-MockCalled -CommandName Write-Error -Times 1 -Scope It -ParameterFilter { $org -eq $Org -and $Sddc -eq $Sddc }
}
}
}
}

View File

@@ -0,0 +1,88 @@
#Requires -Modules Pester, VMware.VMC
Import-Module -Name VMware.VimAutomation.Cis.Core
inModuleScope VMware.VMC {
$functionName = "Get-VMCVMHost"
Describe "$functionName" -Tag 'Unit' {
. "$PSScriptRoot/Shared.ps1"
$global:DefaultVMCServers = $true
$OrgId = "Mocked OrgID"
$SddcId = "MockedSDDCName"
$VMhostName = "Mockedvc_url"
$VMHost_name = "MockedVCmanage_ip"
$esx_state = "MockedVCpublic_ip"
$esx_id = "Mocked_esx_id"
$object = @([PSCustomObject]@{
"resource_config" = @{
esx_hosts = @(@{
esx_id = $esx_id
name = $VMHost_name
hostname = $VMhostName
esx_state = $esx_state
})
}
"id" = $SddcId
"Org_Id" = $OrgId
})
$MockedArray = @($object, $object)
Mock -CommandName Get-VMCSDDC -MockWith { $object }
Mock -CommandName Write-Error -MockWith {}
Context "Sanity checking" {
$command = Get-Command -Name $functionName
defParam $command 'Org'
defParam $command 'Sddc'
}
Context "Behavior testing" {
# Testing single Org with optional SDDC parameter
It "calls Get-VMCVMHost with the Org name supplied" {
{ Get-VMCVMHost -Org $OrgId -sddc $SddcName} | Should Not Throw
Assert-MockCalled -CommandName Get-VMCSDDC -Times 1 -Scope It -ParameterFilter { $Org -eq $OrgId -and $name -eq $SddcName }
}
# Testing single Org without SDDC parameter.
It "calls get-VMCVMHost without SDDC name supplied" {
{ Get-VMCVMHost -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCSDDC -Times 1 -Scope It -ParameterFilter { $org -eq $OrgId }
}
# Testing a single SDDC response
It "gets the task details via list method and returns the properties" {
$(Get-VMCVMHost -Org $OrgId).esx_id | Should -be $esx_id
$(Get-VMCVMHost -Org $OrgId).name | Should -be $VMHost_name
$(Get-VMCVMHost -Org $OrgId).hostname | Should -be $VMhostName
$(Get-VMCVMHost -Org $OrgId).esx_state | Should -be $esx_state
$(Get-VMCVMHost -Org $OrgId).sddc_id | Should -be $SddcId
$(Get-VMCVMHost -Org $OrgId).org_id | Should -be $OrgId
}
# Testing the multiple SDDC response
It "gets the task details of the Org supplied and returns the properties" {
Mock -CommandName Get-VMCSDDC -MockWith { $MockedArray }
$(Get-VMCVMHost -Org $OrgId)[0].esx_id | Should -be $esx_id
$(Get-VMCVMHost -Org $OrgId)[0].name | Should -be $VMHost_name
$(Get-VMCVMHost -Org $OrgId)[0].hostname | Should -be $VMhostName
$(Get-VMCVMHost -Org $OrgId)[0].esx_state | Should -be $esx_state
$(Get-VMCVMHost -Org $OrgId)[0].sddc_id | Should -be $SddcId
$(Get-VMCVMHost -Org $OrgId)[0].org_id | Should -be $OrgId
$(Get-VMCVMHost -Org $OrgId)[1].esx_id | Should -be $esx_id
$(Get-VMCVMHost -Org $OrgId)[1].name | Should -be $VMHost_name
$(Get-VMCVMHost -Org $OrgId)[1].hostname | Should -be $VMhostName
$(Get-VMCVMHost -Org $OrgId)[1].esx_state | Should -be $esx_state
$(Get-VMCVMHost -Org $OrgId)[1].sddc_id | Should -be $SddcId
$(Get-VMCVMHost -Org $OrgId)[1].org_id | Should -be $OrgId
}
It "writes an error if not connected" {
$global:DefaultVMCServers = $false
{ Get-VMCVMHost -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Write-Error -Times 1 -Scope It -ParameterFilter { $org -eq $Org -and $Sddc -eq $Sddc }
}
}
}
}

View File

@@ -0,0 +1,82 @@
#Requires -Modules Pester, VMware.VMC
Import-Module -Name VMware.VimAutomation.Cis.Core
inModuleScope VMware.VMC {
$functionName = "Get-VMCOrg"
Describe "$functionName" -Tag 'Unit' {
. "$PSScriptRoot/Shared.ps1"
$global:DefaultVMCServers = $true
$display_name = "MockedDisplayName"
$user_name = "MockedUserName"
$OrgName = "MockedDisplayName"
$created = "MockedDate"
$id = "MockedId"
$Service = "com.vmware.vmc.orgs"
$MockedList = [PSCustomObject]@{
"display_name" = $display_name
"name" = $OrgName
"created" = $created
"user_name" = $user_name
"id" = $id
}
$object = [PSCustomObject]@{}
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedList }
$MockedArray = @($MockedList, $MockedList)
Mock -CommandName Get-VMCService -MockWith { $object }
Mock -CommandName Write-Error -MockWith {}
Context "Sanity checking" {
$command = Get-Command -Name $functionName
defParam $command 'Name'
}
Context "Behavior testing" {
It "calls get-service to com.vmware.vmc.orgs" {
{ Get-VMCOrg -name $OrgName } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCService -Times 1 -Scope It -ParameterFilter { $name -eq $Service }
}
# Testing a single SDDC response
It "gets the orgs via list method and returns the properties" {
$object = [PSCustomObject]@{}
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedList }
$(Get-VMCOrg).display_name | Should -be $display_name
$(Get-VMCOrg).name | Should -be $OrgName
$(Get-VMCOrg).user_name | Should -be $user_name
$(Get-VMCOrg).created | Should -be $created
$(Get-VMCOrg).id | Should -be $id
}
# Testing the multiple SDDC response
It "calls the Connect-CisServer" {
$object = [PSCustomObject]@{}
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedArray }
{ Get-VMCOrg -name $OrgName } | Should Not Throw
$(Get-VMCOrg -name $OrgName)[0].display_name | Should -be $display_name
$(Get-VMCOrg -name $OrgName)[0].name | Should -be $OrgName
$(Get-VMCOrg -name $OrgName)[0].user_name | Should -be $user_name
$(Get-VMCOrg -name $OrgName)[0].created | Should -be $created
$(Get-VMCOrg -name $OrgName)[0].id | Should -be $id
$(Get-VMCOrg -name $OrgName)[1].display_name | Should -be $display_name
$(Get-VMCOrg -name $OrgName)[1].name | Should -be $OrgName
$(Get-VMCOrg -name $OrgName)[1].user_name | Should -be $user_name
$(Get-VMCOrg -name $OrgName)[1].created | Should -be $created
$(Get-VMCOrg -name $OrgName)[1].id | Should -be $id
}
It "gets writes an error if not connected" {
$global:DefaultVMCServers = $false
{ Get-VMCOrg -name $OrgName } | Should Not Throw
Assert-MockCalled -CommandName Write-Error -Times 1 -Scope It -ParameterFilter { $org -eq $Org -and $Sddc -eq $Sddc }
}
}
}
}

View File

@@ -0,0 +1,98 @@
#Requires -Modules Pester, VMware.VMC
Import-Module -Name VMware.VimAutomation.Cis.Core
inModuleScope VMware.VMC {
$functionName = "Get-VMCSDDCDefaultCredential"
Describe "$functionName" -Tag 'Unit' {
. "$PSScriptRoot/Shared.ps1"
$global:DefaultVMCServers = $true
$OrgId = "Mocked OrgID"
$SddcName = "MockedSDDCName"
$vc_url = "Mockedvc_url"
$vc_management_ip = "MockedVCmanage_ip"
$vc_public_ip = "MockedVCpublic_ip"
$cloud_username = "MockedCloudUser"
$cloud_password = "MockedCloudPass"
$MockedList = [PSCustomObject]@{
"vc_url" = $vc_url
"vc_management_ip" = $vc_management_ip
"vc_public_ip" = $vc_public_ip
"cloud_username" = $cloud_username
"cloud_password" = $cloud_password
}
$MockedList2 = [PSCustomObject]@{
"vc_url" = $vc_url
"vc_management_ip" = $vc_management_ip
"vc_public_ip" = $vc_public_ip
"cloud_username" = $cloud_username
"cloud_password" = $cloud_password
}
$object = [PSCustomObject]@{
"resource_config" = @($MockedList)
}
$MockedArray = @{
"resource_config" = @($MockedList, $MockedList2)
}
Mock -CommandName Get-VMCSDDC -MockWith { $object }
Mock -CommandName Write-Error -MockWith {}
Mock -CommandName Select-Object { $MockedList }
Context "Sanity checking" {
$command = Get-Command -Name $functionName
defParam $command 'Org'
defParam $command 'Sddc'
}
Context "Behavior testing" {
# Testing single Org with optional SDDC parameter
It "calls Get-VMCSDDC with the Org name supplied" {
{ Get-VMCSDDCDefaultCredential -Org $OrgId -sddc $SddcName} | Should Not Throw
Assert-MockCalled -CommandName Get-VMCSDDC -Times 1 -Scope It -ParameterFilter { $Org -eq $OrgId -and $name -eq $SddcName }
}
# Testing single Org without SDDC parameter.
It "calls get-VMCSDDC without SDDC name supplied" {
{ Get-VMCSDDCDefaultCredential -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCSDDC -Times 1 -Scope It -ParameterFilter { $org -eq $OrgId }
}
# Testing a single SDDC response
It "gets the task details via list method and returns the properties" {
$(Get-VMCSDDCDefaultCredential -Org $OrgId).vc_url | Should -be $vc_url
$(Get-VMCSDDCDefaultCredential -Org $OrgId).vc_management_ip | Should -be $vc_management_ip
$(Get-VMCSDDCDefaultCredential -Org $OrgId).vc_public_ip | Should -be $vc_public_ip
$(Get-VMCSDDCDefaultCredential -Org $OrgId).cloud_username | Should -be $cloud_username
$(Get-VMCSDDCDefaultCredential -Org $OrgId).cloud_password | Should -be $cloud_password
Assert-MockCalled -CommandName Select-Object -Times 1 -Scope It
}
# Testing the multiple SDDC response
It "gets the task details of the Org supplied and returns the properties" {
Mock -CommandName Get-VMCSDDC -MockWith { $MockedArray }
$(Get-VMCSDDCDefaultCredential -Org $OrgId)[0].vc_url | Should -be $vc_url
$(Get-VMCSDDCDefaultCredential -Org $OrgId)[0].vc_management_ip | Should -be $vc_management_ip
$(Get-VMCSDDCDefaultCredential -Org $OrgId)[0].vc_public_ip | Should -be $vc_public_ip
$(Get-VMCSDDCDefaultCredential -Org $OrgId)[0].cloud_username | Should -be $cloud_username
$(Get-VMCSDDCDefaultCredential -Org $OrgId)[0].cloud_password | Should -be $cloud_password
$(Get-VMCSDDCDefaultCredential -Org $OrgId)[1].vc_url | Should -be $vc_url
$(Get-VMCSDDCDefaultCredential -Org $OrgId)[1].vc_management_ip | Should -be $vc_management_ip
$(Get-VMCSDDCDefaultCredential -Org $OrgId)[1].vc_public_ip | Should -be $vc_public_ip
$(Get-VMCSDDCDefaultCredential -Org $OrgId)[1].cloud_username | Should -be $cloud_username
$(Get-VMCSDDCDefaultCredential -Org $OrgId)[1].cloud_password | Should -be $cloud_password
Assert-MockCalled -CommandName Select-Object -Times 2 -Scope It
}
It "writes an error if not connected" {
$global:DefaultVMCServers = $false
{ Get-VMCSDDCDefaultCredential -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Write-Error -Times 1 -Scope It -ParameterFilter { $org -eq $Org -and $Sddc -eq $Sddc }
}
}
}
}

View File

@@ -0,0 +1,72 @@
#Requires -Modules Pester, VMware.VMC
Import-Module -Name VMware.VimAutomation.Cis.Core
inModuleScope VMware.VMC {
$functionName = "Get-VMCSDDCPublicIP"
Describe "$functionName" -Tag 'Unit' {
. "$PSScriptRoot/Shared.ps1"
$global:DefaultVMCServers = $true
$OrgId = "Mocked OrgID"
$SddcName = "MockedSDDCName"
$public_ip_pool = "MockedPublic_ip_pool"
$MockedList = [PSCustomObject]@{
"public_ip_pool" = $public_ip_pool
}
$MockedList2 = [PSCustomObject]@{
"public_ip_pool" = $public_ip_pool
}
$object = [PSCustomObject]@{
"resource_config" = @($MockedList)
}
$MockedArray = @{
"resource_config" = @($MockedList, $MockedList2)
}
Mock -CommandName Get-VMCSDDC -MockWith { $object }
Mock -CommandName Write-Error -MockWith {}
Context "Sanity checking" {
$command = Get-Command -Name $functionName
defParam $command 'Org'
defParam $command 'Sddc'
}
Context "Behavior testing" {
# Testing single Org with optional SDDC parameter
It "calls Get-VMCSDDC with the Org name supplied" {
{ Get-VMCSDDCPublicIP -Org $OrgId -sddc $SddcName} | Should Not Throw
Assert-MockCalled -CommandName Get-VMCSDDC -Times 1 -Scope It -ParameterFilter { $Org -eq $OrgId -and $name -eq $SddcName }
}
# Testing single Org without SDDC parameter.
It "calls get-VMCSDDC without SDDC name supplied" {
{ Get-VMCSDDCPublicIP -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCSDDC -Times 1 -Scope It -ParameterFilter { $org -eq $OrgId }
}
# Testing a single SDDC response
It "gets the task details via list method and returns the properties" {
$(Get-VMCSDDCPublicIP -Org $OrgId) | Should -be $Public_ip_pool
#Assert-MockCalled -CommandName Select-Object -Times 1 -Scope It
}
# Testing the multiple SDDC response
It "gets the task details of the Org supplied and returns the properties" {
Mock -CommandName Get-VMCSDDC -MockWith { $MockedArray }
$(Get-VMCSDDCPublicIP -Org $OrgId)[0] | Should -be $Public_ip_pool
$(Get-VMCSDDCPublicIP -Org $OrgId)[1] | Should -be $Public_ip_pool
#Assert-MockCalled -CommandName Select-Object -Times 2 -Scope It
}
It "writes an error if not connected" {
$global:DefaultVMCServers = $false
{ Get-VMCSDDCPublicIP -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Write-Error -Times 1 -Scope It -ParameterFilter { $org -eq $Org -and $Sddc -eq $Sddc }
}
}
}
}

View File

@@ -0,0 +1,75 @@
#Requires -Modules Pester, VMware.VMC
Import-Module -Name VMware.VimAutomation.Cis.Core
inModuleScope VMware.VMC {
$functionName = "Get-VMCSDDCVersion"
Describe "$functionName" -Tag 'Unit' {
. "$PSScriptRoot/Shared.ps1"
$global:DefaultVMCServers = $true
$Service = "com.vmware.vmc.orgs.sddcs"
$OrgId = "Mocked OrgID"
$SddcName = "MockedSDDCName"
$version = "MockedVersion"
$orgs = @(
[PSCustomObject]@{
"Id" = $OrgId
"Org_Id" = $OrgId
})
$MockedServiceObj = [PSCustomObject]{}
$ServicesObject = @([PSCustomObject]@{
"resource_config" = @{
sddc_manifest = [PSCustomObject]@{
version = $version
}
}
})
Mock -CommandName Get-VMCOrg -MockWith { $orgs }
Mock -CommandName Get-VMCService -MockWith { $MockedServiceObj }
$MockedServiceObj | Add-Member -MemberType ScriptMethod -Name "list" -Value { $ServicesObject }
Mock -CommandName Write-Error -MockWith {}
Context "Sanity checking" {
$command = Get-Command -Name $functionName
defParam $command 'Org'
defParam $command 'Name'
}
Context "Behavior testing" {
# Testing single Org with optional SDDC parameter
It "calls Get-VMCSDDCVersion with the Org name supplied" {
{ Get-VMCSDDCVersion -Org $OrgId -Name $SddcName} | Should Not Throw
Assert-MockCalled -CommandName Get-VMCOrg -Times 1 -Scope It -ParameterFilter { $Name -eq $OrgId }
}
It "calls get-service to com.vmware.vmc.orgs.sddcs" {
{ Get-VMCSDDCVersion -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCService -Times 1 -Scope It -ParameterFilter { $name -eq $Service }
}
# Testing a single SDDC response
It "gets the task details via list method and returns the properties" {
$(Get-VMCSDDCVersion -Org $OrgId).version | Should -be $version
}
# Testing the multiple SDDC response
It "gets the task details of the Org supplied and returns the properties" {
Mock -CommandName Get-VMCOrg -MockWith { @($orgs, $orgs) }
$(Get-VMCSDDCVersion -Org $OrgId)[0].version | Should -be $version
$(Get-VMCSDDCVersion -Org $OrgId)[1].version | Should -be $version
}
It "writes an error if not connected" {
$global:DefaultVMCServers = $false
{ Get-VMCSDDCVersion -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Write-Error -Times 1 -Scope It -ParameterFilter { $org -eq $Org -and $Sddc -eq $Sddc }
}
}
}
}

View File

@@ -0,0 +1,89 @@
#Requires -Modules Pester, VMware.VMC
Import-Module -Name VMware.VimAutomation.Cis.Core
inModuleScope VMware.VMC {
$functionName ="Get-VmcSddc"
Describe "$functionName" -Tag 'Unit' {
. "$PSScriptRoot/Shared.ps1"
$global:DefaultVMCServers = $true
$OrgId = "Mocked OrgID"
$name = "MockedSDDCName"
$Notname = "NotTheName"
$Service = "com.vmware.vmc.orgs.sddcs"
$MockedList = [PSCustomObject]@{
"name" = $name
}
$MockedList2 = [PSCustomObject]@{
"name" = $Notname
}
$object = @(
@{"Id" = 1}
)
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedList }
$MockedArray = @($MockedList, $MockedList2)
Mock -CommandName Get-VMCService -MockWith { $object }
Mock -CommandName Get-VMCOrg { $object }
Mock -CommandName Write-Error -MockWith {}
Context "Sanity checking" {
$command = Get-Command -Name $functionName
defParam $command 'Name'
defParam $command 'Org'
}
Context "Behavior testing" {
It "calls Get-VMCOrg" {
{ Get-VMCSDDC -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCOrg -Times 1 -Scope It
}
It "calls Get-VMCOrg with the SDDC name supplied" {
{ Get-VMCSDDC -Org $OrgId -name $name} | Should Not Throw
Assert-MockCalled -CommandName Get-VMCOrg -Times 1 -Scope It -ParameterFilter { $name -eq $name }
}
# Testing with single "Org" so assert call twice.
It "calls get-service to com.vmware.vmc.orgs.sddcs" {
{ Get-VMCSDDC -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCService -Times 1 -Scope It -ParameterFilter { $name -eq $Service }
}
# Testing with two "Orgs" so assert call twice.
It "calls get-service to com.vmware.vmc.orgs.sddcs" {
$object = @(
@{"Id" = 1}
@{"Id" = 2}
)
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedArray }
{ Get-VMCSDDC -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCService -Times 2 -Scope It -ParameterFilter { $name -eq $Service }
}
# Testing a single SDDC response
It "gets the SDDC details via list method and returns the properties" {
$object = [PSCustomObject]@{}
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedList }
$(Get-VMCSDDC -Org $OrgId).name | Should -be $name
}
# Testing the multiple SDDC response
It "gets the SDDC details of the SDDC supplied and returns the properties" {
$object = @{}
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedArray }
$(Get-VMCSDDC -Org $OrgId -name $name).name | Should -be $name
}
It "gets writes an error if not connected" {
$global:DefaultVMCServers = $false
{ Get-VMCSDDC -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Write-Error -Times 1 -Scope It -ParameterFilter { $org -eq $Org -and $Sddc -eq $Sddc }
}
}
}
}

View File

@@ -0,0 +1,87 @@
#Requires -Modules Pester, VMware.VMC
Import-Module -Name VMware.VimAutomation.Cis.Core
inModuleScope VMware.VMC {
$functionName = "Get-VMCTask"
Describe "$functionName" -Tag 'Unit' {
. "$PSScriptRoot/Shared.ps1"
$global:DefaultVMCServers = $true
$OrgId = "Mocked OrgID"
$name = "MockedSDDCName"
$Notname = "NotTheName"
$id = "MockedId"
$Service = "com.vmware.vmc.orgs.tasks"
$MockedList = [PSCustomObject]@{
"name" = $name
}
$MockedList2 = [PSCustomObject]@{
"name" = $Notname
}
$object = @(
@{"Id" = $Id}
)
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedList }
$MockedArray = @($MockedList, $MockedList2)
Mock -CommandName Get-VMCService -MockWith { $object }
Mock -CommandName Get-VMCOrg { $object }
Mock -CommandName Write-Error -MockWith {}
Context "Sanity checking" {
$command = Get-Command -Name $functionName
defParam $command 'Org'
}
Context "Behavior testing" {
It "calls Get-VMCOrg with the Org name supplied" {
{ Get-VMCTask -Org $name} | Should Not Throw
Assert-MockCalled -CommandName Get-VMCOrg -Times 1 -Scope It -ParameterFilter { $name -eq $name }
}
# Testing with single "Org" so assert call twice.
It "calls get-service to com.vmware.vmc.orgs.tasks" {
{ Get-VMCTask -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCService -Times 1 -Scope It -ParameterFilter { $name -eq $Service }
}
# Testing with two "Orgs" so assert call twice.
It "calls get-service to com.vmware.vmc.orgs.tasks" {
$object = @(
@{"Id" = 1}
@{"Id" = 2}
)
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedArray }
{ Get-VMCTask -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Get-VMCService -Times 2 -Scope It -ParameterFilter { $name -eq $Service }
}
# Testing a single SDDC response
It "gets the task details via list method and returns the properties" {
$object = [PSCustomObject]@{}
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedList }
$(Get-VMCTask -Org $OrgId).name | Should -be $name
}
# Testing the multiple SDDC response
It "gets the task details of the SDDC supplied and returns the properties" {
$object = @{}
$object | Add-Member -MemberType ScriptMethod -Name "list" -Value { $MockedArray }
$(Get-VMCTask -Org $OrgId)[0].name | Should -be $name
$(Get-VMCTask -Org $OrgId)[1].name | Should -be $Notname
}
It "gets writes an error if not connected" {
$global:DefaultVMCServers = $false
{ Get-VMCTask -Org $OrgId } | Should Not Throw
Assert-MockCalled -CommandName Write-Error -Times 1 -Scope It -ParameterFilter { $org -eq $Org -and $Sddc -eq $Sddc }
}
}
}
}

View File

@@ -0,0 +1,6 @@
#Requires -Modules Pester
function defParam($command, $name) {
It "Has a -$name parameter" {
$command.Parameters.Item($name) | Should Not BeNullOrEmpty
}
}

View File

@@ -0,0 +1,4 @@
Remove-Module VMware.VMC
import-module ../Modules/VMware.VMC/VMware.VMC.psm1
invoke-pester ./Functions -CodeCoverage ..\Modules\VMware.VMC\VMware.VMC.psm1

View File

@@ -0,0 +1,145 @@
function Apply-OMRightsizing {
<#
.NOTES
===========================================================================
Created by: Markus Kraus
===========================================================================
Changelog:
2020.07 ver 1.0 Base Release
===========================================================================
External Code Sources:
-
===========================================================================
Tested Against Environment:
vSphere Version: vSphere 6.7 U3
PowerCLI Version: PowerCLI 11.5
PowerShell Version: 5.1
OS Version: Windows 10
Keyword: vSphere, vRealize, Rightsizing
===========================================================================
.DESCRIPTION
This function views or applies rightsizing recommendations from vRealize Operations to your vSphere VMs.
.Example
Get-VM -Name test-* | Get-OMResource | Apply-OMRightsizing -ViewOnly | Sort-Object DownSizeMemGB, DownSizeCPU -Descending | Format-Table -AutoSize
.Example
Get-VM -Name test-* | Get-OMResource | Apply-OMRightsizing -Apply -NoUpsizing
.PARAMETER OMResources
vRealize Operations Ressources to process
.PARAMETER ViewOnly
View Recommendations
.PARAMETER Apply
Apply Recommendations
.PARAMETER NoUpsizing
Apply only Downsizing Recommendations
#Requires PS -Version 5.1
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="11.5.0.0"}
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0, HelpMessage = "OM Ressources to process")]
[ValidateNotNullorEmpty()]
$OMResources,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, ParameterSetName="ViewOnly", HelpMessage = "View Recommendations")]
[Switch] $ViewOnly,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, ParameterSetName="Apply", HelpMessage = "Apply Recommendations")]
[Switch] $Apply,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, ParameterSetName="Apply", HelpMessage = "Apply only Downsizing Recommendations")]
[Switch] $NoUpsizing
)
Process {
if ($ViewOnly -or $Apply){
"Collecting Report ..."
$View = @()
foreach ($OMResource in $OMResources){
$DownSize = ($OMResource | Get-OMStat -Key "summary|oversized" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
$UpSize = ($OMResource | Get-OMStat -Key "summary|undersized" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
# Mem is in KB
if($DownSize -gt 0){
$DownSizeMem = ($OMResource | Get-OMStat -Key "summary|oversized|memory" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
$DownSizeCPU = ($OMResource | Get-OMStat -Key "summary|oversized|vcpus" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
}
else {
$DownSizeMem = 0
$DownSizeCPU = 0
}
# Mem is in KB
if($UpSize -gt 0){
$UpSizeMem = ($OMResource | Get-OMStat -Key "summary|undersized|memory" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
$UpSizeCPU = ($OMResource | Get-OMStat -Key "summary|undersized|vcpus" -From ([DateTime]::Now).AddMinutes(-120) | Select-Object -Last 1).Value
}
else {
$UpSizeMem = 0
$UpSizeCPU = 0
}
$Report = [PSCustomObject] @{
Name = $OMResource.name
DownSize = $DownSize
UpSize = $UpSize
DownSizeMem = $DownSizeMem
DownSizeMemGB = [Math]::Round(($DownSizeMem / 1048576), 0)
DownSizeCPU = $DownSizeCPU
UpSizeMem = $UpSizeMem
UpSizeMemGB = [Math]::Round(($UpSizeMem / 1048576), 0)
UpSizeCPU = $upSizeCPU
}
$View += $Report
}
}
if ($ViewOnly){
$View
}
if ($Apply){
foreach ($Object in $View) {
if ($Object.DownSize -gt 0 -or $Object.UpSize -gt 0){
"Processing '$($Object.Name)' ..."
$VM = Get-VM -Name $Object.Name
"Shut down '$($Object.Name)' ..."
$VM | Shutdown-VMGuest -Confirm:$False
$i = 0
while((Get-VM -Name $VM.Name).PowerState -eq "PoweredOn"){
$i++
Start-Sleep 1
Write-Progress -Activity "Check PowerState" -Status "Wait for PowerState Task..."
}
"Create Snapshot for '$($Object.Name)' ..."
$VM | New-Snapshot -Name "Pre Resize" -Memory:$false -Quiesce:$false
if ($Object.DownSize -gt 0){
"Downsize '$($Object.Name)' ..."
$VM | Set-VM -NumCPU $($VM.NumCpu - $Object.DownSizeCPU) -MemoryGB $($VM.MemoryGB - $Object.DownSizeMemGB) -Confirm:$False
}
if ($Object.UpSize -gt 0 -and $NoUpsizing -eq $False){
"Upsize '$($Object.Name)' ..."
$VM = Get-VM -Name $Object.Name
$VM | Set-VM -NumCPU $($VM.NumCpu + $Object.UpSizeCPU) -MemoryGB $($VM.MemoryGB + $Object.UpSizeMemGB) -Confirm:$False
}
#$VM = Get-VM -Name $Object.Name
#$VM | Get-VMResourceConfiguration | Set-VMResourceConfiguration -CpuReservationMhz $($VM.NumCpu * 200) -MemReservationGB $($VM.MemoryGB / 2) -Confirm:$False
"Power on '$($Object.Name)' ..."
$VM | Start-VM -Confirm:$False
}
}
}
}
}

View File

@@ -0,0 +1,144 @@
function Get-VMHostUplinkDetails {
<#
.NOTES
===========================================================================
Created by: Markus Kraus
===========================================================================
Changelog:
2017.03 ver 1.0 Base Release
2020.03 ver 1.1 Add LLDP Support
===========================================================================
External Code Sources:
Get-CDP Version from @LucD22
https://communities.vmware.com/thread/319553
LLDP PowerCLI Tweak
https://tech.zsoldier.com/2018/05/vmware-get-cdplldp-info-from.html
===========================================================================
Tested Against Environment:
vSphere Version: vSphere 6.7 U3
PowerCLI Version: PowerCLI 11.5
PowerShell Version: 5.1
OS Version: Server 2016
Keyword: ESXi, Network, CDP, LLDP, VDS, vSwitch, VMNIC
===========================================================================
.DESCRIPTION
This Function collects detailed informations about your ESXi Host connections to pSwitch and VDS / vSwitch.
LLDP Informations might only be available when uplinks are connected to a VDS.
.Example
Get-VMHost -Name MyHost | Get-VMHostUplinkDetails -Type LLDP | Where-Object {$_.VDS -ne "-No Backing-"} | Format-Table -AutoSize
.Example
Get-VMHost -Name MyHost | Get-VMHostUplinkDetails -Type CDP | Where-Object {$_.VDS -ne "-No Backing-"} | Sort-Object ClusterName, HostName, vmnic | Format-Table -AutoSize
.Example
Get-Cluster -Name MyCluster | Get-VMHost | Get-VMHostUplinkDetails -Type LLDP | Format-Table -AutoSize
.Example
Get-Cluster -Name MyCluster | Get-VMHost | Get-VMHostUplinkDetails -Type CDP | Format-Table -AutoSize
.PARAMETER myHosts
Hosts to process
#Requires PS -Version 5.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 = "Specifies the hosts for which you want to retrieve the uplink details.")]
[ValidateNotNullorEmpty()]
[Alias("myHosts")]
[VMware.VimAutomation.Types.VMHost[]] $VMHost,
[Parameter(Mandatory=$True, ValueFromPipeline=$False, Position=1, HelpMessage = "Type of infos you want to collect (CDP / LLDP)")]
[ValidateSet("CDP","LLDP")]
[String] $Type
)
Begin {
function Get-Info ($VMhostToProcess){
$VMhostProxySwitch = $VMhostToProcess.NetworkInfo.ExtensionData.ProxySwitch
$VMhostSwitch = $VMhostToProcess.NetworkInfo.VirtualSwitch
$objReport = @()
$VMhostToProcess| ForEach-Object{Get-View $_.ID} |
ForEach-Object{ Get-View $_.ConfigManager.NetworkSystem} |
ForEach-Object{ foreach($physnic in $_.NetworkInfo.Pnic){
if($Type -eq "CDP"){
$obj = "" | Select-Object ClusterName,HostName,vmnic,PCI,MAC,VDS,vSwitch,CDP_Port,CDP_Device,CDP_Address
}
elseif($Type -eq "LLDP"){
$obj = "" | Select-Object ClusterName,HostName,vmnic,PCI,MAC,VDS,vSwitch,LLDP_Port,LLDP_Chassis,LLDP_SystemName
}
else {
Throw "Invalide Type"
}
$pnicInfo = $_.QueryNetworkHint($physnic.Device)
foreach($hint in $pnicInfo){
$obj.ClusterName = $VMhostToProcess.parent.name
$obj.HostName = $VMhostToProcess.name
$obj.vmnic = $physnic.Device
$obj.PCI = $physnic.PCI
$obj.MAC = $physnic.Mac
if ($backing = ($VMhostProxySwitch | Where-Object {$_.Spec.Backing.PnicSpec.PnicDevice -eq $physnic.Device})) {
$obj.VDS = $backing.DvsName
}
else {
$obj.VDS = "-No Backing-"
}
if ($backing = ($VMhostSwitch | Where-Object {$_.Nic -eq $physnic.Device})) {
$obj.vSwitch = $backing.name
}
else {
$obj.vSwitch = "-No Backing-"
}
if($Type -eq "CDP"){
if( $hint.ConnectedSwitchPort ) {
$obj.CDP_Port = $hint.ConnectedSwitchPort.PortId
$obj.CDP_Device = $hint.ConnectedSwitchPort.DevId
$obj.CDP_Address = $hint.ConnectedSwitchPort.Address
}
else {
$obj.CDP_Port = "-No Info-"
$obj.CDP_Device = "-No Info-"
$obj.CDP_Address = "-No Info-"
}
}
if($Type -eq "LLDP"){
if( $hint.LldpInfo ) {
$obj.LLDP_Port = $hint.LldpInfo.PortId
$obj.LLDP_Chassis = $hint.LldpInfo.ChassisId
$obj.LLDP_SystemName = ($hint.LldpInfo.Parameter | Where-Object key -eq "System Name").Value
}
else {
$obj.LLDP_Port = "-No Info-"
$obj.LLDP_Chassis = "-No Info-"
$obj.LLDP_SystemName = "-No Info-"
}
}
}
$objReport += $obj
}
}
$objReport
}
}
Process {
$VMHost | Foreach-Object { Write-Output (Get-Info $_) }
}
}

View File

@@ -0,0 +1,225 @@
function Set-VMHostSecureNTP {
<#
.NOTES
===========================================================================
Created by: Markus Kraus
===========================================================================
Changelog:
2020.05 ver 1.0 Base Release
===========================================================================
External Code Sources:
-
===========================================================================
Tested Against Environment:
vSphere Version: vSphere 6.7 U3
PowerCLI Version: PowerCLI 11.5
PowerShell Version: 5.1
OS Version: Windows 10
Keyword: ESXi, NTP, Hardening, Security, Firewall
===========================================================================
.DESCRIPTION
This function sets new NTP Servers on given ESXi Hosts and configures the host firewall to only accept NTP connections from these servers.
.Example
Get-VMHost | Set-VMHostSecureNTP -Secure
.Example
Get-VMHost | Set-VMHostSecureNTP -Type SetSecure -NTP 10.100.1.1, 192.168.2.1
.PARAMETER VMHost
Specifies the hosts to configure
.PARAMETER SetSecure
Execute Set and Secure operation for new NTP Servers
.PARAMETER NTP
Specifies a Array of NTP Servers
.PARAMETER Secure
Execute Secure operation for exitsting NTP Servers
#Requires PS -Version 5.1
#Requires -Modules VMware.VimAutomation.Core, @{ModuleName="VMware.VimAutomation.Core";ModuleVersion="11.5.0.0"}
#>
[CmdletBinding()]
param(
[Parameter(Mandatory=$True, ValueFromPipeline=$True, Position=0, HelpMessage = "Specifies the hosts to configure.")]
[ValidateNotNullorEmpty()]
[VMware.VimAutomation.Types.VMHost[]] $VMHost,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, ParameterSetName="SetSecure", HelpMessage = "Execute Set and Secure operation for new NTP Servers")]
[Switch] $SetSecure,
[Parameter(Mandatory=$True, ValueFromPipeline=$False, ParameterSetName="SetSecure", HelpMessage = "Specifies a Array of NTP Servers")]
[ValidateNotNullorEmpty()]
[ipaddress[]] $NTP,
[Parameter(Mandatory=$False, ValueFromPipeline=$False, ParameterSetName="Secure", HelpMessage = "Execute Secure operation for exitsting NTP Servers")]
[Switch] $Secure
)
begin {
function SetNTP ($MyHost) {
## Get NTP Service
"Get NTP Service from VMHost ..."
$NTPService = $MyHost | Get-VMHostService | Where-Object {$_.key -eq "ntpd"}
## Stop NTP Service if running
"Stop NTP Service if running ..."
if($NTPService.Running -eq $True){
Stop-VMHostService -HostService $NTPService -Confirm:$false | Out-Null
}
## Enable NTP Service
"Enable NTP Service if disabled..."
if($NTPService.Policy -ne "on"){
Set-VMHostService -HostService $NTPService -Policy "on" -confirm:$False | Out-Null
}
## Remove all existing NTP Servers
"Remove all existing NTP Servers ..."
try {
$MyHost | Get-VMHostNtpServer | Foreach-Object {
Remove-VMHostNtpServer -VMHost $MyHost -NtpServer $_ -Confirm:$false
}
}
catch [System.Exception] {
Write-Warning "Error during removing existing NTP Servers on Host '$($MyHost.Name)'."
}
## Set New NTP Servers
"Set New NTP Servers ..."
foreach ($myNTP in $NTP) {
$MyHost | Add-VMHostNtpServer -ntpserver $myNTP -confirm:$False | Out-Null
}
## Set Current time on Host
"Set Current time on VMHost ..."
$HostTimeSystem = Get-View $MyHost.ExtensionData.ConfigManager.DateTimeSystem
$HostTimeSystem.UpdateDateTime([DateTime]::UtcNow)
## Start NTP Service
"Start NTP Service ..."
Start-VMHostService -HostService $NTPService -confirm:$False | Out-Null
## Get New NTP Servers
"Get New NTP Servers ..."
$NewNTPServers = $MyHost | Get-VMHostNtpServer
"`tNew NTP Servers: $($NewNTPServers -join ", ")"
}
function SecureNTP ($MyHost) {
## Get NTP Servers
"Get NTP Servers to Secure ..."
[Array]$CurrentNTPServers = $MyHost | Get-VMHostNtpServer
"`tNTP Servers: $($CurrentNTPServers -join ", ")"
## Get ESXCLI -V2
$esxcli = Get-ESXCLI -VMHost $MyHost -v2
## Get NTP Client Firewall
"Get NTP Client Firewall ..."
try {
$FirewallGet = $esxcli.network.firewall.get.Invoke()
}
catch [System.Exception] {
Write-Warning "Error during Rule List. See latest errors..."
}
"`tLoded: $($FirewallGet.Loaded)"
"`tEnabled: $($FirewallGet.Enabled)"
"`tDefaultAction: $($FirewallGet.DefaultAction)"
## Get NTP Client Firewall Rule
"Get NTP Client Firewall RuleSet ..."
$esxcliargs = $esxcli.network.firewall.ruleset.list.CreateArgs()
$esxcliargs.rulesetid = "ntpClient"
try {
$FirewallRuleList = $esxcli.network.firewall.ruleset.list.Invoke($esxcliargs)
}
catch [System.Exception] {
Write-Warning "Error during Rule List. See latest errors..."
}
"`tEnabled: $($FirewallRuleList.Enabled)"
## Set NTP Client Firewall Rule
"Set NTP Client Firewall Rule ..."
$esxcliargs = $esxcli.network.firewall.ruleset.set.CreateArgs()
$esxcliargs.enabled = "true"
$esxcliargs.allowedall = "false"
$esxcliargs.rulesetid = "ntpClient"
try {
$esxcli.network.firewall.ruleset.set.Invoke($esxcliargs)
}
catch [System.Exception] {
$ErrorMessage = $_.Exception.Message
if ($ErrorMessage -ne "Already use allowed ip list") {
Write-Warning "Error during Rule Set. See latest errors..."
}
}
"Get NTP Client Firewall Rule AllowedIP ..."
$esxcliargs = $esxcli.network.firewall.ruleset.allowedip.list.CreateArgs()
$esxcliargs.rulesetid = "ntpClient"
try {
$FirewallRuleAllowedIPList = $esxcli.network.firewall.ruleset.allowedip.list.Invoke($esxcliargs)
}
catch [System.Exception] {
Write-Warning "Error during Rule List. See latest errors..."
}
"`tAllowed IP Addresses: $($FirewallRuleAllowedIPList.AllowedIPAddresses -join ", ")"
## Remove Existing IP from firewall rule
"Remove Existing IP from firewall rule ..."
if ($FirewallRuleAllowedIPList.AllowedIPAddresses -ne "All") {
foreach ($IP in $FirewallRuleAllowedIPList.AllowedIPAddresses) {
$esxcliargs = $esxcli.network.firewall.ruleset.allowedip.remove.CreateArgs()
$esxcliargs.rulesetid = "ntpClient"
$esxcliargs.ipaddress = $IP
try {
$esxcli.network.firewall.ruleset.allowedip.remove.Invoke($esxcliargs)
}
catch [System.Exception] {
Write-Warning "Error during AllowedIP remove. See latest errors..."
}
}
}
## Set NTP Client Firewall Rule AllowedIP
"Set NTP Client Firewall Rule AllowedIP ..."
foreach ($myNTP in $CurrentNTPServers) {
$esxcliargs = $esxcli.network.firewall.ruleset.allowedip.add.CreateArgs()
$esxcliargs.ipaddress = $myNTP
$esxcliargs.rulesetid = "ntpClient"
try {
$esxcli.network.firewall.ruleset.allowedip.add.Invoke($esxcliargs)
}
catch [System.Exception] {
$ErrorMessage = $_.Exception.Message
if ($ErrorMessage -ne "Ip address already exist.") {
Write-Warning "Error during AllowedIP remove. See latest errors..."
}
}
}
## Get New NTP Client Firewall Rule AllowedIP
"Get New NTP Client Firewall Rule AllowedIP ..."
$esxcliargs = $esxcli.network.firewall.ruleset.allowedip.list.CreateArgs()
$esxcliargs.rulesetid = "ntpClient"
try {
$FirewallRuleAllowedIPList = $esxcli.network.firewall.ruleset.allowedip.list.Invoke($esxcliargs)
}
catch [System.Exception] {
Write-Warning "Error during Rule List. See latest errors..."
}
"`tNew Allowed IP Addresses: $($FirewallRuleAllowedIPList.AllowedIPAddresses -join ", ")"
}
}
process {
if ($SetSecure) {
"Execute Set and Secure operation for new NTP Servers ..."
$VMHost | Foreach-Object { Write-Output (SetNTP $_) }
$VMHost | Foreach-Object { Write-Output (SecureNTP $_) }
}
if ($Secure) {
"Execute Secure operation for exitsting NTP Servers ..."
$VMHost | Foreach-Object { Write-Output (SecureNTP $_) }
}
}
}