Merge branch 'master' into master
This commit is contained in:
@@ -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 {}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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 = ''
|
||||
|
||||
}
|
||||
356
Modules/VMware.WorkloadManagement/VMware.WorkloadManagement.psm1
Normal file
356
Modules/VMware.WorkloadManagement/VMware.WorkloadManagement.psm1
Normal 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"
|
||||
}
|
||||
}
|
||||
69
Pester/Functions/Connect-VMCVIServer.tests.ps1
Normal file
69
Pester/Functions/Connect-VMCVIServer.tests.ps1
Normal 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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
23
Pester/Functions/Get-VMCCommand.tests.ps1
Normal file
23
Pester/Functions/Get-VMCCommand.tests.ps1
Normal 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' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Pester/Functions/Get-VMCFirewallRule.tests.ps1
Normal file
75
Pester/Functions/Get-VMCFirewallRule.tests.ps1
Normal 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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
88
Pester/Functions/Get-VMCHost.tests.ps1
Normal file
88
Pester/Functions/Get-VMCHost.tests.ps1
Normal 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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
82
Pester/Functions/Get-VMCOrg.tests.ps1
Normal file
82
Pester/Functions/Get-VMCOrg.tests.ps1
Normal 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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
98
Pester/Functions/Get-VMCSDDCDefaultCredential.tests.ps1
Normal file
98
Pester/Functions/Get-VMCSDDCDefaultCredential.tests.ps1
Normal 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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
72
Pester/Functions/Get-VMCSDDCPublicIP.tests.ps1
Normal file
72
Pester/Functions/Get-VMCSDDCPublicIP.tests.ps1
Normal 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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
75
Pester/Functions/Get-VMCSDDCVersion.tests.ps1
Normal file
75
Pester/Functions/Get-VMCSDDCVersion.tests.ps1
Normal 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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
89
Pester/Functions/Get-VmcSddc.tests.ps1
Normal file
89
Pester/Functions/Get-VmcSddc.tests.ps1
Normal 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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
87
Pester/Functions/Get-VmcTask.tests.ps1
Normal file
87
Pester/Functions/Get-VmcTask.tests.ps1
Normal 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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
6
Pester/Functions/Shared.ps1
Normal file
6
Pester/Functions/Shared.ps1
Normal file
@@ -0,0 +1,6 @@
|
||||
#Requires -Modules Pester
|
||||
function defParam($command, $name) {
|
||||
It "Has a -$name parameter" {
|
||||
$command.Parameters.Item($name) | Should Not BeNullOrEmpty
|
||||
}
|
||||
}
|
||||
4
Pester/VMCCode-Coverage.ps1
Normal file
4
Pester/VMCCode-Coverage.ps1
Normal 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
|
||||
145
Scripts/Apply-OMRightsizing.ps1
Normal file
145
Scripts/Apply-OMRightsizing.ps1
Normal 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
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
144
Scripts/Get-VMHostUplinkDetails.ps1
Normal file
144
Scripts/Get-VMHostUplinkDetails.ps1
Normal 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 $_) }
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
225
Scripts/Set-VMHostSecureNTP.ps1
Normal file
225
Scripts/Set-VMHostSecureNTP.ps1
Normal 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 $_) }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user