Adding scripts

This commit is contained in:
ackitsme committed 2026-07-24 17:35:40 -07:00
1 parent e78eed48b6
commit fc7cfeb008
10 files changed
+2321

No files matched your search

+226
View File
@@ -0,0 +1,226 @@
param (
[string]$vCenter = "",
[string]$dvSwitch = "",
[string]$CSVFile = "",
[switch]$SaveCred = $false,
[switch]$Help = $false
)
# Variables
$fileVersion = "1.0.0"
$fileDate = "2026-01-28"
# Display Script Banner
Write-Host "--------------------------------------------------" -ForegroundColor White
Write-Host "dvSwitch Port Group Creation Script" -ForegroundColor Green
Write-Host "Version $($FileVersion) ($($FileDate))" -ForegroundColor Green
Write-Host "Written by Charlie Silverman" -ForegroundColor Green
Write-Host "--------------------------------------------------" -ForegroundColor White
if ($Help) {
Write-Host
Write-Host "Purpose: Create dvSwitch Port Groups en masse."
Write-Host "Command Syntax:"
Write-Host " CreatedvSwitchPortGroups.ps1 (-vcenter [vcenter host name]) (-dvSwitch ""[dvswitch]"") (-CSVFile ""[csvfile]"")"
Write-Host " (-savecred) (-help)`n" -foregroundcolor green
Write-Host "Command Line Options:"
Write-Host
Write-Host -NoNewLine " -vCenter " -foregroundcolor Green
Write-Host "- The FQDN or IP address of a vCenter server."
Write-Host -NoNewLine " -dvSwitch " -foregroundcolor Green
Write-Host "- The name of the distributed virtual switch in vCenter."
Write-Host -NoNewLine " -CSVfile " -foregroundcolor Green
Write-Host "- The path to the CSV file. See note below for format."
Write-Host -NoNewLine " -savecred " -foregroundcolor Green
Write-Host "- Configure and store vCenter server credentials. This will only store the credentials under"
Write-Host " the current logged in user."
Write-Host -NoNewLine " -help " -foregroundcolor Green
Write-Host "- Display command help."
Write-Host
Write-Host "If any of the information is not provided, you will be prompted. If a credential has been previously stored, it will"
Write-Host "be used again unless the -savecred option is specified."
Write-Host
Write-Host "The CSV file must follow the format listed below. The only field required is PortGroup. Fields can be in any order."
Write-Host " PortGroup, VLAN, PortBinding, NumPorts, ActiveUplink, DisabledUplink, StandbyUplink, Notes"
Write-Host "Where:"
Write-Host " Portgroup " -ForegroundColor Green -NoNewLine
Write-Host " - The name of the port group."
Write-Host " VLAN " -ForegroundColor Green -NoNewLine
Write-Host " - [Optional] The VLAN tag for the port group."
Write-Host " PortBinding " -ForegroundColor Green -NoNewLine
Write-Host " - [Optional] The type of port binding for the port group. This can be either Static or Dynamic."
Write-Host " Defaults to Static if not specified."
Write-Host " NumPorts " -ForegroundColor Green -NoNewLine
Write-Host " - [Optional] The number of ports for the port group. This is ignored for a dynamic port group."
Write-Host " Defaults to 254 if not specified."
Write-Host " ActiveUplink " -ForegroundColor Green -NoNewLine
Write-Host " - [Optional] A comma delimited list of switch uplinks to be set as active for the port group."
Write-Host " StandbyUplink " -ForegroundColor Green -NoNewLine
Write-Host " - [Optional] A comma delimited list of switch uplinks to be set as standby for the port group."
Write-Host " UnusedUplink " -ForegroundColor Green -NoNewLine
Write-Host " - [Optional] A comma delimited list of switch uplinks to be set as unused for the port group."
Write-Host " Notes " -ForegroundColor Green -NoNewLine
Write-Host " - [Optional] Notes to add to the port group."
exit
}
$quiet = Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
if ($vCenter -eq "") {
$vCenter = Read-Host "Enter name of vCenter Server"
}
if ($SaveCred) {
$credential = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
$credential | Export-Clixml -path $env:USERPROFILE\kistools-$vcenter.cred
Write-Host "Saving credentials."
}
if (Test-Path -path $env:USERPROFILE\kistools-$vcenter.cred -PathType Leaf) {
$credentials = Import-Clixml -path $env:USERPROFILE\kistools-$vcenter.cred
Write-Host "Using stored credentials"
} else {
$credentials = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
if (!$credentials) {
Write-Host "ERROR: No credentials were entered" -foregroundcolor yellow
}
}
try {
Write-Host -NoNewLine "Connecting to vCenter $vcenter..."
$vcconn = Connect-VIServer $vcenter -Credential $credentials -ErrorAction Stop
Write-Host " Success" -ForegroundColor green
} catch {
Write-Host " Failure" -ForegroundColor Yellow -BackgroundColor Red
exit
}
try {
if ($dvSwitch -ne "") {
get-VDswitch $dvSwitch -ErrorAction Stop
}
} catch {
Write-Host "ERROR: dvSwitch ""$dvSwitch"" is not found." -ForegroundColor Red
$dvSwitch = ""
}
if ($dvSwitch -eq "") {
$dvSwitchlist = Get-VDSwitch | Sort-Object
While (($dvSwitch -eq "") -or (-not $dvSwitch)) {
Write-Host "`ndvSwitch Selection:`n"
for ($x = 0; $x -lt $dvSwitchlist.length; $x++) {
Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($DVSwitchlist[$x].name)" -ForegroundColor Yellow
}
$dvSwitchNum = [int](Read-Host "`nSelect dvSwitch Number") - 1
$dvSwitch = $dvSwitchlist[$dvSwitchNum]
}
$mySwitch = get-VDSwitch $dvSwitch
} else {
$mySwitch = get-VDSwitch $dvSwitch
}
$csvdata = Import-CSV $csvfile
Write-Host "Processing Port Group List"
for ($x = 0; $x -lt $csvdata.length; $x++) {
$pgname = $csvdata[$x].PortGroup
if ($pgname -eq "") { continue }
if (-not ($pgvlan = $csvdata[$x].VLAN)) {
$pgvlan = 0
}
if (-not ($pgbinding = $csvdata[$x].PortBinding)) {
$pgbinding = "Static"
}
if (-not ($pgports = $csvdata[$x].NumPorts)) {
$pgports = 254
}
if ($pgactive -and (($pgactive = ($csvdata[$x].ActiveUplink).split(",")).count -eq 0)) {
$pgactive = @()
}
if ($pgstandby -and (($pgstandby = ($csvdata[$x].StandbyUplink).split(",")).count -eq 0)) {
$pgstandby = @()
}
if ($pgunused -and (($pgunused = ($csvdata[$x].UnusedUplink).split(",")).count -eq 0)) {
$pgunused = @()
}
Write-Host "$pgname... " -NoNewLine
if ($temp = Get-VdPortGroup $pgname -erroraction silentlycontinue) {
Write-Host " Already Exists - Skipping" -ForegroundColor Yellow
continue
}
try {
$newpg = New-VdPortGroup -name "$pgname" -vlanid $pgvlan -PortBinding $pgbinding -VdSwitch "$dvSwitch" -erroraction stop
Write-Host "Created Successfully" -ForegroundColor Green
} catch {
Write-Host " ERROR - Unable to Create Port Group $pgname on dvSwitch $dvSwitch." -ForegroundColor Red
Write-Host "$($_.Exception.Message)" -ForegroundColor Gray
continue
}
$myuplinks = @()
foreach($uplink in $pgactive) {
if ($uplink -eq "") { continue }
if (($mySwitch.ExtensionData.Config.UplinkPortPolicy.UplinkPortName | Where-Object {$_ -eq $uplink}).Count -eq 0) {
Write-Host "Warning: Uplink ""$uplink"" for Active is not found on switch $dvSwitch" -ForegroundColor Yellow
continue
}
$myuplinks += $uplink
}
if ($myuplinks.Count -gt 0) {
Write-Host " Assigning active uplink ports... " -NoNewLine
try {
$temp = $newpg | Get-VDUplinkTeamingPolicy | Set-VDUplinkTeamingPolicy -ActiveUplinkPort $myuplinks -ErrorAction Stop
Write-Host "Success" -ForegroundColor Green
} catch {
Write-Host "ERROR assigning uplinks to $pgname" -ForegroundColor Red
Write-Host "$($_.Exception.Message)" -ForegroundColor Gray
}
}
$myuplinks = @()
foreach($uplink in $pgstandby) {
if ($uplink -eq "") { continue }
if (($mySwitch.ExtensionData.Config.UplinkPortPolicy.UplinkPortName | Where-Object {$_ -eq $uplink}).Count -eq 0) {
Write-Host "Warning: Uplink ""$uplink"" for STANDBY is not found on switch $dvSwitch" -ForegroundColor Yellow
continue
}
$myuplinks += $uplink
}
if ($myuplinks.Count -gt 0) {
Write-Host " Assigning standby uplink ports... " -NoNewLine
try {
$temp = $newpg | Get-VDUplinkTeamingPolicy | Set-VDUplinkTeamingPolicy -StandbyUplinkPort $myuplinks -ErrorAction Stop
Write-Host "Success" -ForegroundColor Green
} catch {
Write-Host "ERROR assigning standby uplinks to $pgname" -ForegroundColor Red
Write-Host "$($_.Exception.Message)" -ForegroundColor Gray
}
}
$myuplinks = @()
foreach($uplink in $pgunused) {
if ($uplink -eq "") { continue }
if (($mySwitch.ExtensionData.Config.UplinkPortPolicy.UplinkPortName | Where-Object {$_ -eq $uplink}).Count -eq 0) {
Write-Host "Warning: Uplink ""$uplink"" for UNUSED is not found on switch $dvSwitch" -ForegroundColor Yellow
continue
}
$myuplinks += $uplink
}
if ($myuplinks.Count -gt 0) {
Write-Host " Assigning unused uplink ports... " -NoNewLine
try {
$temp = $newpg | Get-VDUplinkTeamingPolicy | Set-VDUplinkTeamingPolicy -UnusedUplinkPort $myuplinks -ErrorAction Stop
Write-Host "Success" -ForegroundColor Green
} catch {
Write-Host "ERROR assigning unused uplinks to $pgname" -ForegroundColor Red
Write-Host "$($_.Exception.Message)" -ForegroundColor Gray
}
}
}
+118
View File
@@ -0,0 +1,118 @@
Function Get-DrsGroup {
<#
.SYNOPSIS
Retrieves DRS groups from a cluster.
.DESCRIPTION
Retrieves DRS groups from a cluster.
.PARAMETER Cluster
Specify the cluster for which you want to retrieve the DRS groups
.PARAMETER Name
Specify the name of the DRS group you want to retrieve.
.EXAMPLE
Get-DrsGroup -Cluster $Cluster -Name "VMs DRS Group"
Retrieves the DRS group "Vms DRS Group" from cluster $Cluster.
.EXAMPLE
Get-Cluster | Get-DrsGroup
Retrieves all the DRS groups for all clusters.
.INPUTS
ClusterImpl
.OUTPUTS
ClusterVmGroup
ClusterHostGroup
.COMPONENT
VMware vSphere PowerCLI
#>
param([parameter(Mandatory=$true, ValueFromPipeline=$true)]$Cluster,
[string] $Name="*")
process {
$Cluster = Get-Cluster -Name $Cluster
if($Cluster) {
$Cluster.ExtensionData.ConfigurationEx.Group | `
Where-Object {$_.Name -like $Name}
}
}
}
Function Add-VMToDrsGroup {
<#
.SYNOPSIS
Adds a virtual machine to a cluster VM DRS group.
.DESCRIPTION
Adds a virtual machine to a cluster VM DRS group.
.PARAMETER Cluster
Specify the cluster for which you want to retrieve the DRS groups
.PARAMETER DrsGroup
Specify the DRS group you want to retrieve.
.PARAMETER VM
Specify the virtual machine you want to add to the DRS Group.
.EXAMPLE
Add-VMToDrsGroup -Cluster $Cluster -DrsGroup "VM DRS Group" -VM $VM
Adds virtual machine $VM to the DRS group "VM DRS Group" of cluster $Cluster.
.EXAMPLE
Get-Cluster MyCluster | Get-VM "A*" | Add-VMToDrsGroup -Cluster MyCluster -DrsGroup $DrsGroup
Adds all virtual machines with a name starting with "A" in cluster MyCluster to the DRS group $DrsGroup of cluster MyCluster.
.INPUTS
VirtualMachineImpl
.OUTPUTS
Task
.COMPONENT
VMware vSphere PowerCLI
#>
param([parameter(Mandatory=$true)] $Cluster,
[parameter(Mandatory=$true)] $DrsGroup,
[parameter(Mandatory=$true, ValueFromPipeline=$true)] $VM)
begin {
$Cluster = Get-Cluster -Name $Cluster
}
process {
if ($Cluster) {
if ($DrsGroup.GetType().Name -eq "string") {
$DrsGroupName = $DrsGroup
$DrsGroup = Get-DrsGroup -Cluster $Cluster -Name $DrsGroup
}
if (-not $DrsGroup) {
Write-Error "The DrsGroup $DrsGroupName was not found on cluster $($Cluster.name)."
}
else {
if ($DrsGroup.GetType().Name -ne "ClusterVmGroup") {
Write-Error "The DrsGroup $DrsGroupName on cluster $($Cluster.Name) doesn't have the required type ClusterVmGroup."
}
else {
$VM = $Cluster | Get-VM -Name $VM
If ($VM) {
$spec = New-Object VMware.Vim.ClusterConfigSpecEx
$spec.groupSpec = New-Object VMware.Vim.ClusterGroupSpec[] (1)
$spec.groupSpec[0] = New-Object VMware.Vim.ClusterGroupSpec
$spec.groupSpec[0].operation = "edit"
$spec.groupSpec[0].info = $DrsGroup
$spec.groupSpec[0].info.vm += $VM.ExtensionData.MoRef
$Cluster.ExtensionData.ReconfigureComputeResource_Task($spec, $true)
}
}
}
}
}
}
+675
View File
@@ -0,0 +1,675 @@
param (
[string]$vCenter = "",
[string]$Cluster = "",
[string]$dvSwitch = "",
[string]$Datastore = "",
[string]$SourceVMName = "",
[string]$Folder = "",
[string]$CSVFile = "",
[switch]$SaveCred = $false,
[switch]$Help = $false
)
Import-Module .\DRSGroupFunctions.ps1
function GetFolderFromPath($folder) {
$parts = $folder.Split("\")
if ($parts.length -eq 0) { return $folder }
for ($x = 0; $x -lt $parts.length; ++$x) {
$thispart = $parts[$x]
if ($x -gt 0) {
$thisfolder = Get-Folder $parts[$x] | Where-Object {$_.Parent.Id -eq $parent.Id}
} else {
$thisfolder = Get-Folder $parts[$x] | Where-Object {$_.Parent.Name -eq "vm"}
}
$parent = $thisfolder
}
return $thisfolder
}
# Variables
$fileVersion = "1.2.0"
$fileDate = "2026-06-03"
# Display Script Banner
Write-Host "--------------------------------------------------" -ForegroundColor White
Write-Host "vSphere Testing VM Deployment Script" -ForegroundColor Green
Write-Host "Version $($FileVersion) ($($FileDate))" -ForegroundColor Green
Write-Host "Written by Charlie Silverman" -ForegroundColor Green
Write-Host "--------------------------------------------------" -ForegroundColor White
if ($Help) {
Write-Host
Write-Host "Purpose: Deploy testing VMs for a set of port groups."
Write-Host "Command Syntax:"
Write-Host " DeployTestingVMs.ps1 (-vcenter [vCenter]) (-Cluster ""[Cluster]"") (-dvSwitch ""[dvswitch]"")" -ForegroundColor green
Write-Host " (-SourceVMName ""[SourceVMName]"") (-CSVFile ""[csvfile]"")" -ForegroundColor green
Write-Host "Command Line Options:"
Write-Host
Write-Host -NoNewLine " -vCenter " -ForegroundColor Green
Write-Host "- The FQDN or IP address of a vCenter server."
Write-Host -NoNewLine " -Cluster " -ForegroundColor Green
Write-Host "- The name of the Cluster in vCenter."
Write-Host -NoNewLine " -dvSwitch " -ForegroundColor Green
Write-Host "- The name of the distributed virtual switch in vCenter."
Write-Host -NoNewLine " -SourceVMName " -ForegroundColor Green
Write-Host "- The name of the distributed virtual switch in vCenter."
Write-Host -NoNewLine " -CSVfile " -ForegroundColor Green
Write-Host "- The path to the CSV file. See note below for format."
Write-Host -NoNewLine " -savecred " -ForegroundColor Green
Write-Host "- Configure and store vCenter server credentials. This will only store the credentials under"
Write-Host " the current logged in user."
Write-Host -NoNewLine " -help " -ForegroundColor Green
Write-Host "- Display command help."
Write-Host
Write-Host "If any of the information is not provided, you will be prompted. If a credential has been previously stored, it will"
Write-Host "be used again unless the -savecred option is specified."
Write-Host
Write-Host "The CSV file must follow the format listed below. The only field required is PortGroup. Fields can be in any order."
Write-Host " VLAN, Description, IPAddress, Netmask, Gateway, Site"
Write-Host "Where:"
Write-Host " VLAN " -ForegroundColor Green -NoNewLine
Write-Host " - The VLAN tag for the port group."
Write-Host " Description " -ForegroundColor Green -NoNewLine
Write-Host " - The Description for the port group."
Write-Host " IPAddress " -ForegroundColor Green -NoNewLine
Write-Host " - IP address for the VM."
Write-Host " Netmask " -ForegroundColor Green -NoNewLine
Write-Host " - Netmask for the network."
Write-Host " Gateway " -ForegroundColor Green -NoNewLine
Write-Host " - Default gateway for the network."
Write-Host " Site " -ForegroundColor Green -NoNewLine
Write-Host " - The site prefix to be used for DRS group configuration."
Write-Host ""
Write-Host "The port group name will be assumed to be in the following format: ""[Description] - VLAN[VLAN]"""
Write-Host "If the VLAN tag is 12 and the description is ""Big Servers"", the port group name will be ""Big Servers - VLAN12"""
Write-Host ""
Write-Host "The DRS group name will be assumed to be in the following format: ""[Site] Only VMs"""
Write-Host "If the Site is Primary, the DRS group name will be ""Primary Only VMs"""
Write-Host ""
Write-Host "Additionally, the new VM names will be in the format ""KISStress - VLAN[VLAN]"""
exit
}
try {
$data = import-csv $CSVFile
} catch {
Write-Host "ERROR: Input file is not in a valid format." -ForegroundColor Yellow -BackgroundColor Red
Write-Host "Message: $($_.Exception.Message)" -ForegroundColor yellow
exit
}
if (!($data | Where-Object {$_.PSObject.Properties.Name -contains "VLAN"}) -or (!($data | Where-Object {$_.PSObject.Properties.Name -contains "Description"}))) {
Write-Host "ERROR: Input file is not in a valid format." -ForegroundColor Yellow -BackgroundColor Red
exit
}
$setip = $false
if ($data | Where-Object {$_.PSObject.Properties.Name -contains "IPAddress"}) {
if ($data | Where-Object {$_.PSObject.Properties.Name -contains "Netmask"}) {
if ($data | Where-Object {$_.PSObject.Properties.Name -contains "Gateway"}) {
$setip = $true
}
}
}
if ($vCenter -eq "") {
$vCenter = Read-Host "Enter name of vCenter Server"
}
if ($SaveCred) {
$credential = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
$credential | Export-Clixml -path $env:USERPROFILE\kistools-$vcenter.cred
Write-Host "Saving credentials."
}
if (Test-Path -path $env:USERPROFILE\kistools-$vcenter.cred -PathType Leaf) {
$credentials = Import-Clixml -path $env:USERPROFILE\kistools-$vcenter.cred
Write-Host "Using stored credentials"
} else {
$credentials = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
if (!$credentials) {
Write-Host "ERROR: No credentials were entered" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
Write-Host "Operation Terminated" -ForegroundColor Yellow
exit
}
}
try {
Write-Host -NoNewLine "Connecting to vCenter $vcenter... "
$vcconn = Connect-VIServer $vcenter -Credential $credentials -ErrorAction Stop
Write-Host "Success" -ForegroundColor green
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
Write-Host "Message: $($_.Exception.Message)" -ForegroundColor yellow
Write-Host "Operation Terminated" -ForegroundColor Yellow
exit
}
if ($Cluster -eq "") {
$Clusterlist = Get-Cluster | Sort-Object
$startpos = 0
$step = 10
While (($Cluster -eq "") -or (-not $Cluster)) {
$endpos = $startpos + 10;
if ($endpos -gt $Clusterlist.length) { $endpos = $Clusterlist.length }
$page = $startpos / $step + 1
$maxpage = [math]::Ceiling($Clusterlist.length / $step)
Write-Host "`nCluster Selection (Page $page of $maxpage):`n"
if ($startpos -gt 0) {
Write-Host " 0" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "<< Previous Page" -ForegroundColor White
}
for ($x = $startpos; $x -lt $endpos; $x++) {
Write-Host "$(([string]($x+1-$startpos)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($Clusterlist[$x].name)" -ForegroundColor Yellow
}
if ($endpos -lt $Clusterlist.length) {
Write-Host " $($step+1)" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host ">> Next Page" -ForegroundColor White
}
$Clusternum = Read-Host "`nSelect Cluster Number"
$Clusternum = [int]$Clusternum - 1
if ($Clusternum -eq -1) {
$startpos -= $step
continue
}
if ($Clusternum -eq $step) {
$startpos += $step
continue
}
$Cluster = $Clusterlist[$Clusternum + $startpos].Name
}
}
try {
Write-Host "Validating cluster ""$Cluster""... " -NoNewLine
$mycluster = get-cluster $Cluster
Write-Host "Success" -ForegroundColor Green
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "ERROR: Unable to locate cluster ""$Cluster"" in $vCenter" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
Write-Host "Operation Terminated" -ForegroundColor Yellow
exit
}
if ($dvSwitch -eq "") {
$myhost = $mycluster | Get-VMHost | Select-Object -First 1
$SwitchList = Get-VdSwitch -VMHost $myhost
$startpos = 0
$step = 10
While (($dvSwitch -eq "") -or (-not $dvSwitch)) {
$endpos = $startpos + 10;
if ($endpos -gt $SwitchList.length) { $endpos = $SwitchList.length }
$page = $startpos / $step + 1
$maxpage = [math]::Ceiling($SwitchList.length / $step)
Write-Host "`ndvSwitch Selection (Page $page of $maxpage):`n"
if ($startpos -gt 0) {
Write-Host " 0" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "<< Previous Page" -ForegroundColor White
}
for ($x = $startpos; $x -lt $endpos; $x++) {
Write-Host "$(([string]($x+1-$startpos)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($SwitchList[$x].name)" -ForegroundColor Yellow
}
if ($endpos -lt $SwitchList.length) {
Write-Host " $($step+1)" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host ">> Next Page" -ForegroundColor White
}
$dvSwitchnum = Read-Host "`nSelect dvSwitch Number"
$dvSwitchnum = [int]$dvSwitchnum - 1
if ($dvSwitchnum -eq -1) {
$startpos -= $step
continue
}
if ($dvSwitchnum -eq $step) {
$startpos += $step
continue
}
$dvSwitch = $SwitchList[$dvSwitchnum + $startpos].Name
}
}
try {
Write-Host "Validating dvSwitch ""$dvSwitch""... " -NoNewLine
$mydvSwitch = Get-VdSwitch $dvSwitch
Write-Host "Success" -ForegroundColor Green
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "ERROR: Unable to locate dvSwitch $dvSwitch in $vCenter" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
exit
}
if ($SourceVMName -eq "") {
$VMList = $mycluster | Get-VM
$startpos = 0
$step = 10
While (($SourceVMName -eq "") -or (-not $SourceVMName)) {
$endpos = $startpos + 10;
if ($endpos -gt $VMList.length) { $endpos = $VMList.length }
$page = $startpos / $step + 1
$maxpage = [math]::Ceiling($VMList.length / $step)
Write-Host "`nSource VM Selection (Page $page of $maxpage):`n"
if ($startpos -gt 0) {
Write-Host " 0" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "<< Previous Page" -ForegroundColor White
}
for ($x = $startpos; $x -lt $endpos; $x++) {
Write-Host "$(([string]($x+1-$startpos)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($VMlist[$x].name)" -ForegroundColor Yellow
}
if ($endpos -lt $VMList.length) {
Write-Host " $($step+1)" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host ">> Next Page" -ForegroundColor White
}
$VMnum = Read-Host "`nSelect VM Number"
$VMnum = [int]$VMnum - 1
if ($VMnum -eq -1) {
$startpos -= $step
continue
}
if ($VMnum -eq $step) {
$startpos += $step
continue
}
$SourceVMName = $VMlist[$VMnum + $startpos].Name
}
}
try {
Write-Host "Locating source VM ""$SourceVMName""... " -NoNewLine
if ($abyss = Get-VM $SourceVMName -ErrorAction Stop) {
Write-Host "Success" -ForegroundColor Green
} else {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
Write-Host "Operation Aborted" -ForegroundColor Yellow
}
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "ERROR: Error locating VM $SourceVMName in $vCenter" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
Write-Host "Operation Terminated" -ForegroundColor Yellow
exit
}
if ($Datastore -eq "") {
$DSList = $mycluster | Get-Datastore | Where-Object {$_.ExtensionData.Host.Count -gt 1}
$startpos = 0
$step = 10
While (($Datastore -eq "") -or (-not $Datastore)) {
$endpos = $startpos + 10;
if ($endpos -gt $DSList.length) { $endpos = $DSList.length }
$page = $startpos / $step + 1
$maxpage = [math]::Ceiling($DSList.length / $step)
Write-Host "`nDatastore Selection (Page $page of $maxpage):`n"
if ($startpos -gt 0) {
Write-Host " 0" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "<< Previous Page" -ForegroundColor White
}
for ($x = $startpos; $x -lt $endpos; $x++) {
Write-Host "$(([string]($x+1-$startpos)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($DSlist[$x].name)" -ForegroundColor Yellow
}
if ($endpos -lt $DSList.length) {
Write-Host " $($step+1)" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host ">> Next Page" -ForegroundColor White
}
$dvSwitchnum = Read-Host "`nSelect Datastore Number"
$dvSwitchnum = [int]$dvSwitchnum - 1
if ($dvSwitchnum -eq -1) {
$startpos -= $step
continue
}
if ($dvSwitchnum -eq $step) {
$startpos += $step
continue
}
$Datastore = $DSlist[$dvSwitchnum + $startpos].Name
}
}
try {
Write-Host "Locating Datastore ""$Datastore""... " -NoNewLine
$mydatastore = Get-Datastore $Datastore -ErrorAction Stop
if ($mydatastore) {
Write-Host "Success" -ForegroundColor Green
} else {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "ERROR: Unable to locate datastore $Datastore in $Cluster" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
Write-Host "Operation Terminated" -ForegroundColor Yellow
}
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "ERROR: Error locating Datastore $Datastore in $vCenter" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
Write-Host "Operation Terminated" -ForegroundColor Yellow
exit
}
if ($Folder -eq "") {
Write-Host "Inventorying VM Folder Structure..." -NoNewLine
$FolderList = Get-Folder | Where-Object {$_.Parent.Name -eq "vm"} | Sort-Object -Property @{Expression={$_.Name}; Descending=$false}
$FolderList += Get-Folder | Where-Object {($_.Parent.Name -ne "vm") -and ($_.Type -eq "VM") -and $($_.Name -ne "vm")} | Sort-Object -Property @{Expression={$_.Parent.Name}; Descending=$false},@{Expression={$_.Name}; Descending=$false}
Write-Host " Success" -ForegroundColor Green
for($x = 0; $x -lt $FolderList.length; ++$x) {
$thisfolder = $FolderList[$x]
$path = ""
if ($thisfolder.Parent.Name -ne "vm") {
$searchcount = 0
While ($searchcount -lt 10) {
$nextfolder = $thisfolder.Parent
$path = "$($nextfolder.Name)\$($path)"
if ($nextfolder.Parent.Name -ne "vm") {
$thisfolder = $nextfolder
++$searchcount
} else {
$searchcount = 11
}
}
}
if ($path -ne "") {
$path = "$($path)$($Folderlist[$x].Name)"
} else {
$path = $Folderlist[$x].Name
}
$FolderList[$x] | Add-Member -NotePropertyName "FullPath" -NotePropertyValue $path
}
$startpos = 0
$step = 10
While (-not $myfolder) {
$endpos = $startpos + 10;
if ($endpos -gt $FolderList.length) { $endpos = $FolderList.length }
$page = $startpos / $step + 1
$maxpage = [math]::Ceiling($FolderList.length / $step)
Write-Host "`nFolder Selection (Page $page of $maxpage):`n"
if ($startpos -gt 0) {
Write-Host " 0" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "<< Previous Page" -ForegroundColor White
}
for ($x = $startpos; $x -lt $endpos; $x++) {
$path = $Folderlist[$x].FullPath
Write-Host "$(([string]($x+1-$startpos)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$path" -ForegroundColor Yellow
}
if ($endpos -lt $FolderList.length) {
Write-Host " $($step+1)" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host ">> Next Page" -ForegroundColor White
}
$Foldernum = Read-Host "`nSelect Folder Number"
$Foldernum = [int]$Foldernum - 1
if ($Foldernum -eq -1) {
$startpos -= $step
continue
}
if ($Foldernum -eq $step) {
$startpos += $step
continue
}
$Folder = $FolderList[$Foldernum].FullPath
$myfolder = $FolderList[$Foldernum].Name
}
}
try {
Write-Host "Locating Folder ""$Folder""... " -NoNewLine
$myfolder = GetFolderFromPath($Folder)
if ($myfolder) {
Write-Host "Success" -ForegroundColor Green
} else {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
Write-Host "Operation Terminated" -ForegroundColor Yellow
}
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "ERROR: Error locating Folder $Folder in $vCenter" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
Write-Host "Operation Terminated" -ForegroundColor Yellow
exit
}
## Validate that the proper DRS groups exist for each site in the format "[site] Only VMs"
Write-Host "Verifying that the necessary DRS groups exist..."
$sites = $data.Site | Select-Object -Unique -CaseInsensitive
$siteerror = $false
foreach ($site in $sites) {
$sitegroup = "$site Only VMs"
Write-Host " - $sitegroup... " -NoNewLine
try {
$drsg = Get-DrsGroup -Cluster $Cluster -Name $sitegroup
if ($drsg) {
Write-Host "Success" -ForegroundColor Green
} else {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
$siteerror = $true
}
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host "ERROR: Unable to locate DRS group $sitegroup." -ForegroundColor Yellow -BackgroundColor Red -NoNewLine
Write-Host ""
$siteerror = $true
}
}
if ($siteerror) {
Write-Host "Operation Terminated" -ForegroundColor Yellow
exit
}
## Validate that the necessary network port groups exist in the format "[Description] - VLAN[VLAN]"
Write-Host "Verifying that the necessary port groups exist..."
$pgerror = $false
foreach ($row in $data) {
$vlan = [int]$row.VLAN
$description = $row.Description
$myportgroupname = "$description - VLAN$vlan"
Write-Host " - $myportgroupname... " -NoNewLine
try {
$pg = Get-VDPortGroup -Name $myportgroupname
if ($pg) {
Write-Host "Success" -ForegroundColor Green
} else {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
$pgerror = $true
}
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
$pgerror = $true
}
}
if ($pgerror) {
Write-Host "Operation Terminated" -ForegroundColor Yellow
exit
}
exit
foreach($row in $data) {
try {
$abyss = [int]$row.VLAN
} catch {
continue
}
$vlan = [int]$row.VLAN
$description = $row.Description
$myportgroupname = "$description - VLAN$vlan"
$myvmname = "KISStress - VLAN$vlan"
Write-Host
try {
if (Get-VM $myvmname -ErrorAction Silent) {
Write-Host "WARNING: VM ""$myvmname"" already exists. Skipping." -ForegroundColor Yellow
continue
}
} catch {
Write-Host "ERROR: Unable to determine if ""$myvmname"" exists. Skipping." -ForegroundColor Red
continue
}
try {
$myportgroup = Get-VdPortGroup -Name $myportgroupname -VDSwitch $dvswitch
} catch {
Write-Host "ERROR: Could not locate port group ""$myportgroupname"""
continue
}
Write-Host "Cloning ""$SourceVMName"" to VM ""$myvmname""... " -NoNewLine
try {
$task = New-VM -Name $myvmname -VM $SourceVMName -ResourcePool $mycluster -Datastore $Datastore -Location $myfolder -DiskStorageFormat Thin -ErrorAction Silent -RunAsync
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "Message: $($_.Exception.Message)" -ForegroundColor yellow
continue
}
$created = $false
while (($task = Get-Task -iD $task.Id).State -eq "Running") {
Start-Sleep -Seconds 5
Write-Host "." -NoNewLine
}
switch(($task = Get-Task -iD $task.Id).State) {
"Success" {
Write-Host "Success" -ForegroundColor Green
}
"Error" {
if ($task.ExtensionData.Info.Cancelled) {
Write-Host "Failure - Task Cancelled" -ForegroundColor Yellow -BackgroundColor Red
continue
} else {
Write-Host "Failure - Unknown Error" -ForegroundColor Yellow -BackgroundColor Red
continue
}
}
}
$nic = Get-VM $myvmname | Get-NetworkAdapter
try {
Write-Host "Changing NIC on VM ""$myvmname"" to port group ""$myportgroupname""... " -NoNewLine
$task = $nic | Set-NetworkAdapter -Portgroup $myportgroup -Confirm:$false -ErrorAction Stop -RunAsync
while (($task = Get-Task -iD $task.Id).State -eq "Running") {
Start-Sleep -Seconds 1
Write-Host "." -NoNewLine
}
switch(($task = Get-Task -iD $task.Id).State) {
"Success" {
Write-Host "Success" -ForegroundColor Green
}
"Error" {
if ($task.ExtensionData.Info.Cancelled) {
Write-Host "Failure - Task Cancelled" -ForegroundColor Yellow -BackgroundColor Red
} else {
Write-Host "Failure - Unknown Error" -ForegroundColor Yellow -BackgroundColor Red
}
}
}
} catch {
Write-Host " Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "Message: $($_.Exception.Message)" -ForegroundColor yellow
}
if ($row.Site) {
Write-Host "Adding VM ""$myvmname"" to DRS Group ""$($row.Site) Only VMs"" in cluster $Cluster... " -NoNewLine
try {
$task = Add-VMToDrsGroup -Cluster $Cluster -DrsGroup "$($row.Site) Only VMs" -VM $myvmname
$task | Add-Member -NotePropertyName "Id" -NotePropertyValue "Task-$($task.Value)"
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "ERROR: Error adding VM ""$myvmname"" to DRS Group ""$($row.Site) Only VMs""" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "Message: $($_.Exception.Message)" -ForegroundColor yellow
continue
}
while (($task = Get-Task -iD $task.Id).State -eq "Running") {
Start-Sleep -Seconds 1
Write-Host "." -NoNewLine
}
switch(($task = Get-Task -iD $task.Id).State) {
"Success" {
Write-Host "Success" -ForegroundColor Green
}
"Error" {
if ($task.ExtensionData.Info.Cancelled) {
Write-Host "Failure - Task Cancelled" -ForegroundColor Yellow -BackgroundColor Red
} else {
Write-Host "Failure - Unknown Error" -ForegroundColor Yellow -BackgroundColor Red
}
}
}
}
try {
Write-Host "Powering on VM ""$myvmname""... " -NoNewLine
$task = Start-VM $myvmname -ErrorAction Stop -RunAsync
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "Message: $($_.Exception.Message)" -ForegroundColor yellow
}
$booted = $false
while (!$booted) {
if ((Get-VM $myvmname).ExtensionData.Guest.ToolsStatus -eq "toolsOk") {
$booted = $true
continue
}
Start-Sleep 5
Write-Host "." -NoNewLine
}
Write-Host "Success" -ForegroundColor Green
# Update Network Information If Provided
if ($setip) {
$ipaddress = $row.IPAddress
$netmask = $row.netmask
$gateway = $row.Gateway
if (!$ipaddress -or !$netmask -or !$gateway) { continue }
Write-Host "Updating network configuration for vm ""$myvmname""... " -NoNewLine
$ifcfg = "sudo echo 'STARTMODE=auto' > /etc/sysconfig/network/ifcfg-eth0
sudo echo 'BOOTPROTO=static' >> /etc/sysconfig/network/ifcfg-eth0
sudo echo 'IPADDR=$ipaddress' >> /etc/sysconfig/network/ifcfg-eth0
sudo echo 'NETMASK=$netmask' >> /etc/sysconfig/network/ifcfg-eth0
sudo echo 'default $gateway - -' > /etc/sysconfig/network/routes
sudo /etc/init.d/network restart
"
$UserName = "stress"
$Password = ConvertTo-SecureString -String "stress" -AsPlainText -Force
$Credential = New-Object System.Management.Automation.PSCredential -ArgumentList $UserName, $Password
try {
$abyss = Invoke-VMScript $myvmname -ScriptText $ifcfg -GuestCredential $Credential -ScriptType Bash
Write-Host "Success" -ForegroundColor Green
} catch {
Write-Host "Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "Message: $($_.Exception.Message)" -ForegroundColor yellow
}
}
}
+150
View File
@@ -0,0 +1,150 @@
param (
[string]$vCenter = "",
[switch]$SaveCred = $false,
[switch]$Help = $false
)
# Variables
$fileVersion = "1.1.0"
$fileDate = "2025-04-02"
# Display Script Banner
Write-Host "--------------------------------------------------" -ForegroundColor White
Write-Host "vSphere TPM Key Inventory" -ForegroundColor Green
Write-Host "Version $($FileVersion) ($($FileDate))" -ForegroundColor Green
Write-Host "Written by Charlie Silverman" -ForegroundColor Green
Write-Host "--------------------------------------------------" -ForegroundColor White
if ($Help) {
Write-Host
Write-Host "Purpose: Collect TPM encryption keys for all ESXi hosts."
Write-Host "Command Syntax:"
Write-Host " GetKeys.ps1 (-vcenter [vcenter host name]) (-savecred) (-help)"
Write-Host "Command Line Options:"
Write-Host
Write-Host -NoNewLine " -vCenter " -foregroundcolor Green
Write-Host "- The FQDN or IP address of a vCenter server."
Write-Host -NoNewLine " -savecred " -foregroundcolor Green
Write-Host "- Configure and store vCenter server credentials. This will only store the credentials under"
Write-Host " the current logged in user."
Write-Host -NoNewLine " -help " -foregroundcolor Green
Write-Host "- Display command help."
Write-Host
Write-Host "If no any of the information is not provided, you will be prompted. If a credential has been previously stored, it will be used again unless the -savecred option is specified."
Write-Host
exit
}
if (-not (Get-Module -ListAvailable -Name VMware.PowerCLI*)) {
Write-Host "ERROR: VMware PowerCLI is not installed!" -foregroundcolor yellow
exit
}
$hideresult = Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
if ($vCenter -eq "") {
$vCenter = Read-Host "Enter name of vCenter Server"
}
if ($savecred) {
$credential = Get-Credential -Message "Enter credentials for vCenter server $vcenter"
$credential | Export-Clixml -path $env:USERPROFILE\kis-getkeys-$vcenter.cred
Write-Host "Saving credentials."
}
if (Test-Path -path $env:USERPROFILE\kis-getkeys-$vcenter.cred -PathType Leaf) {
$credentials = Import-Clixml -path $env:USERPROFILE\kis-getkeys-$vcenter.cred
Write-Host "Using stored credentials"
} else {
$credentials = Get-Credential -Message "Enter credentials for vCenter server $vcenter"
if (!$credentials) {
Write-Host "ERROR: No credentials were entered" -foregroundcolor yellow
}
}
try {
Write-Host -NoNewLine "Connecting to vCenter $vcenter..."
$vcconn = Connect-VIServer $vcenter -Credential $credentials -ErrorAction SilentlyContinue
Write-Host " Success" -ForegroundColor green
} catch {
Write-Host " Failure" -ForegroundColor Yellow -BackgroundColor Red
exit
}
$now = (Get-Date).ToString("yyyyMMdd_hhmm")
$exportfile = "TPMKeys-$vCenter-$now.csv"
$VMHosts = Get-VMHost | Sort-Object
$VMHostKeys = @()
foreach ($VMHost in $VMHosts) {
$esxcli = Get-EsxCli -VMHost $VMHost -V2
try {
$encryption = $esxcli.system.settings.encryption.get.Invoke()
if ($encryption.Mode -eq "TPM")
{
$key = $esxcli.system.settings.encryption.recovery.list.Invoke()
$hostKey = [pscustomobject]@{
Host = $VMHost.Name
EncryptionMode = $encryption.Mode
RequireExecutablesOnlyFromInstalledVIBs = $encryption.RequireExecutablesOnlyFromInstalledVIBs
RequireSecureBoot = $encryption.RequireSecureBoot
RecoveryID = $key.RecoveryID
RecoveryKey = $key.Key
}
$VMHostKeys += $hostKey
}
else
{
$hostKey = [pscustomobject]@{
Host = $VMHost.Name
EncryptionMode = $encryption.Mode
RequireExecutablesOnlyFromInstalledVIBs = $encryption.RequireExecutablesOnlyFromInstalledVIBs
RequireSecureBoot = $encryption.RequireSecureBoot
RecoveryID = $null
RecoveryKey = $null
}
$VMHostKeys += $hostKey
}
}
catch {
$VMHost.Name + $_
}
}
Write-Host "Exporting TPM keys for all hosts in $vcenter`n to $exportfile..." -NoNewLine
try {
$VMHostKeys | Export-Csv $exportfile
Write-Host " Complete" -ForegroundColor Green
} catch {
Write-Host " Failed" -ForegroundColor Red
exit
}
Write-Host "Attempting to reset all TPM Encryption Recovery Key Backup Alarms..."
# Locate TPM Encrytpion Recovery Key Backup Alarm ID
$alarm = Get-AlarmDefinition "TPM Encryption Recovery Key Backup Alarm"
$alarmID = $alarm.Id -split '-', 2 | select-object -last 1
$alarmMgr = Get-View AlarmManager
foreach ($VMHost in $VMHosts) {
try {
$decalarm = $VMHost.ExtensionData.TriggeredAlarmState | where-object {$_.Alarm.Value -eq $alarmID} | Select-Object -first 1
if ([string]::IsNullorEmpty($decalarm)) {
continue
}
} catch {
Write-Host "Error retrieving alarms for host $VMHost"
continue
}
}
Write-Host "Clearing all yellow alarms from ESXi hosts..."
try {
$filter = New-Object VMware.Vim.AlarmFilterSpec
$filter.Status += [VMware.Vim.ManagedEntityStatus]::yellow
$filter.TypeEntity = [VMware.Vim.AlarmFilterSpecAlarmTypeByEntity]::entityTypeHost
$filter.TypeTrigger = [vmware.vim.AlarmFilterSpecAlarmTypeByTrigger]::triggerTypeAll
$alarmMgr.ClearTriggeredAlarms($filter)
Write-Host " Success" -ForegroundColor Green
} catch {
Write-Host " Failed" -ForegroundColor Red
}
+114
View File
@@ -0,0 +1,114 @@
param (
[string]$vcenter = "",
[switch]$allvms = $false,
[switch]$SaveCred = $false,
[switch]$Help = $false
)
# Variables
$fileVersion = "1.0.0"
$fileDate = "2024-12-11"
$savecred = $false
# Display Script Banner
Write-Host "--------------------------------------------------" -ForegroundColor White
Write-Host "vCenter Snapshot Report" -ForegroundColor Green
Write-Host "Version $($FileVersion) ($($FileDate))" -ForegroundColor Green
Write-Host "Written by Charlie Silverman" -ForegroundColor Green
Write-Host "--------------------------------------------------" -ForegroundColor White
if ($Help) {
Write-Host "Command Syntax:" -ForegroundColor Green
Write-Host 'GetSnaps.ps1 -vcenter="VCURI" [-help] [-savecred]' -ForegroundColor Green
Write-Host ""
Write-Host "Command line options:" -ForegroundColor Green
Write-Host "---------------------" -ForegroundColor Green
Write-Host "-vcenter - Specify the FQDN for the vCenter server" -ForegroundColor Green
Write-Host "-allvms - Get snapshots for all VMs. Omitting this option will only check powered on VMs." -ForegroundColor Green
Write-Host "-savecred - Save Credentials. If credentials were previously saved and this option is not selected," -ForegroundColor Green
Write-Host " they will be used." -ForegroundColor Green
Write-Host "-help - Show this help information." -ForegroundColor Green
exit
}
if ($vcenter -eq "") {
$vcenter = Read-Host "Enter name of vCenter Server"
}
try {
if (Test-Path -Path "$env:USERPROFILE\GetSnaps-${vcenter}.cred" -PathType Leaf) {
Write-Host "Using stored credentials for $vcenter."
$cred = Import-CliXML -path "$env:USERPROFILE\GetSnaps-${vcenter}.cred"
} else {
$cred = Get-Credential -Message "Enter credentials for vCenter $vcenter"
}
$vcenterConnection = connect-viserver $vcenter -credential $cred -ErrorAction Stop
} catch {
Write-Host "ERROR: Invalid credentials or incorrect vCenter FQDN"
Write-Host $_
exit
}
if ($savecred) {
Write-Host "Storing credentials for $vcenter."
$cred | Export-CliXML -Path "$env:USERPROFILE\GetSnaps-${vcenter}.cred"
}
$DesktopPath = [Environment]::GetFolderPath("Desktop")
$now = (Get-Date).ToString("yyyyMMdd_hhmm")
$outputFileName = "$DesktopPath\VMSnapshotList-$now.html"
# Get all VMs
if ($allvms) {
$VMs = Get-VM
} else {
$VMs = Get-VM | Where {$_.PowerState -eq "PoweredOn"}
}
# Create empty array to hold snapshot information
$SnapshotInfo = @()
# Loop through each VM and get snapshot information
foreach ($VM in $VMs) {
$Snapshots = Get-Snapshot -VM $VM
# Loop through each snapshot and add information to array
foreach ($Snapshot in $Snapshots) {
$SnapshotInfo += [PSCustomObject]@{
VMName = $VM.Name
SnapshotName = [System.Uri]::UnescapeDataString($Snapshot.Name)
Created = $Snapshot.Created
Description = $Snapshot.Description
SizeGB = [math]::Round(($Snapshot.SizeGB),2)
}
}
}
# Create HTML output
$HTML = @"
<html>
<head>
<title>Snapshots Report</title>
<style>
body {background-color: #D3D3D3;}
table {border: 3px solid black; border-collapse: collapse; font-size: 14px; font-family: Arial, sans-serif; background-color: #3B3B3B; color: white; max-width: 800px;}
th, td {border: 2px solid black; padding: 10px; text-align: left; width: auto;}
th {background-color: #2F4F4F; font-weight: bold;}
</style>
</head>
<body>
"@
$HTML += $SnapshotInfo | ConvertTo-Html -Fragment -Property VMName, SnapshotName, Created, Description, SizeGB
$HTML += @"
</body>
</html>
"@
# Output HTML to file
$HTML | Out-File -FilePath $outputFileName
# Output confirmation message
Write-Host "Generating Snapshots Report"
Write-Host "Your snapshots report has been saved to: $outputFileName"
# Disconnect from vCenter Server
Disconnect-VIServer -Confirm:$false
+105
View File
@@ -0,0 +1,105 @@
param (
[string]$vcenter = "",
# [switch]$allvms,
[switch]$savecred,
[switch]$Help = $false
)
# Variables
$fileVersion = "1.2.0"
$fileDate = "2024-12-13"
# Display Script Banner
Write-Host "--------------------------------------------------" -ForegroundColor White
Write-Host "vSphere VM Network Assignment Export" -ForegroundColor Green
Write-Host "Version $($FileVersion) ($($FileDate))" -ForegroundColor Green
Write-Host "Written by Charlie Silverman" -ForegroundColor Green
Write-Host "--------------------------------------------------" -ForegroundColor White
if ($Help) {
Write-Host "Command Syntax:" -ForegroundColor Green
Write-Host 'GetVMNetworks.ps1 -vcenter="VCURI" [-help] [-savecred]' -ForegroundColor Green
Write-Host ""
Write-Host "Command line options:" -ForegroundColor Green
Write-Host "---------------------" -ForegroundColor Green
Write-Host "-vcenter - Specify the URI for the vCenter server" -ForegroundColor Green
Write-Host "-savecred - Save Credentials. If credentials were previously saved and this option is not selected," -ForegroundColor Green
Write-Host " they will be used." -ForegroundColor Green
Write-Host "-help - Show this help information." -ForegroundColor Green
exit
}
if ($vcenter -eq "") {
$vcenter = Read-Host "Enter name of vCenter Server"
}
try {
if (Test-Path -Path "$env:USERPROFILE\GetVMNetworks-$vcenter.cred" -PathType Leaf) {
Write-Host "Using stored credentials for $vcenter."
$cred = Import-CliXML -path "$env:USERPROFILE\GetVMNetworks-$vcenter.cred"
} else {
$cred = Get-Credential -Message "Enter credentials for vCenter $vcenter"
}
$vcenterConnection = connect-viserver $vcenter -credential $cred -ErrorAction Stop
} catch {
Write-Host "ERROR: Invalid credentials or incorrect vCenter FQDN"
Write-Host $_
exit
}
if ($savecred) {
Write-Host "Storing credentials for $vcenter."
$cred | Export-CliXML -Path "$env:USERPROFILE\GetVMNetworks-$vcenter.cred"
}
# Output filename
$DesktopPath = [Environment]::GetFolderPath("Desktop")
$now = (Get-Date).ToString("yyyyMMdd_hhmm")
$csvFileName = "$DesktopPath\VMNetworkList-$now.csv"
# Find the maximum number of adapters in a VM to create the CSV header properly
$allvms = get-vm
$maxnics = 0
foreach ($vm in $allvms) {
$adaptercount = ($vm | get-networkadapter | measure).Count
if ($adaptercount -gt $maxnics) {
$maxnics = $adaptercount
}
}
# Write the CSV header
$header = """Cluster"",""VM Name"""
for ($x = 1; $x -le $maxnics; ++$x) {
#write-host -NoNewLine ",Network Adapter $x"
$header = "$header,""Network Adapter $x"""
}
# write-host
$header | Out-File -FilePath $csvFileName -Encoding UTF8
# Get list of clusters
$clusters = get-cluster
# Iterate through cluster list
foreach ($cluster in $clusters) {
# Get list of VMs in the cluster
$vms = $cluster | get-vm | sort-object -Property Name
$clusterName = $cluster.Name
# Iterate through the VM list
foreach($vm in $vms) {
$vmName = $vm.Name
$entry = """$cluster"",""$vmName"""
# Get all network adapters for the VM
$netAdapters = $vm | get-networkadapter
# Iterate through adapter list
foreach ($adapter in $netAdapters) {
# Append port group name for each adapter
$adapterName = $adapter.Name
$adapterPG = $adapter.NetworkName
$entry = "$entry,""$adapterPG"""
}
# Write host entry
#write-Host $entry
$entry | Out-File -FilePath $csvFileName -Append -Encoding UTF8
}
Write-Host "`nData for cluster $clusterName has been saved to the file $csvFileName."
}
+291
View File
@@ -0,0 +1,291 @@
param (
[string]$vCenter = "",
[string]$cluster = "",
[string]$filename = "vmexport.xlsx",
[string]$Customer = "",
[switch]$Help = $false,
[switch]$SaveCred = $false
)
# Variables
$fileVersion = "1.0.0"
$fileDate = "2026-05-21"
$scriptName = Split-Path -Path $PSCommandPath -Leaf
# Display Script Banner
Write-Host "--------------------------------------------------" -ForegroundColor White
Write-Host "Collect VM Information for Upgrades" -ForegroundColor Green
Write-Host "Version $($FileVersion) ($($FileDate))" -ForegroundColor Green
Write-Host "Written by Charlie Silverman" -ForegroundColor Green
Write-Host "--------------------------------------------------" -ForegroundColor White
function CheckModuleInstalled($moduleName, $command) {
Write-Host "Checking that package $moduleName is installed..." -NoNewLine
if (-not(get-command $command -erroraction silentlycontinue)) {
Write-Host " Missing" -ForegroundColor Red
if (-not (Get-Module -ListAvailable -Name $moduleName)) {
$response = ""
while (($response -ne "yes") -and ($response -ne "no")) {
$response = (Read-Host "ImportExcel module not instaled. Install now? (yes/no)").ToLower()
}
if ($response -eq "no") {
Write-Host "Operation Cancelled." -ForegroundColor Yellow
exit
}
Write-Host "Installing PowerShell module $moduleName..." -NoNewLine
Install-Module -Name $moduleName -Scope CurrentUser -Force
Write-Host " Success" -ForegroundColor Green
}
Write-Host "Loading PowerShell module $moduleName..." -NoNewLine
Import-Module $moduleName
Write-Host " Success" -ForegroundColor Green
} else {
Write-Host " Found" -ForegroundColor Green
}
}
# Check for ImportExcel and install if missing
CheckModuleInstalled -moduleName "VCF.PowerCLI" -command "connect-viserver"
CheckModuleInstalled -moduleName "ImportExcel" -command "import-excel"
$moduleName = "ImportExcel"
Import-Module ImportExcel
if ($Help) {
Write-Host
Write-Host "Purpose: Generate a spreadsheet for VM Upgrades."
Write-Host "Command Syntax:"
Write-Host " $scriptName (-vcenter [vcenter host name]) (-cluster ""[cluster]"") (-filename ""[filename]"") (-customer ""[customer]""" -foregroundcolor green
Write-Host "Command Line Options:"
Write-Host
Write-Host -NoNewLine " -vCenter " -foregroundcolor Green
Write-Host "- The FQDN or IP address of a vCenter server."
Write-Host -NoNewLine " -cluster " -foregroundcolor Green
Write-Host "- The name of the cluster as shown in vCenter."
Write-Host -NoNewLine " -customer " -foregroundcolor Green
Write-Host "- The name of the customer to display on the sheet title."
Write-Host -NoNewLine " -filename " -foregroundcolor Green
Write-Host "- The CSV filename to save the result."
Write-Host
Write-Host "If any of the information is not provided, you will be prompted. If a credential has been previously stored, it will"
Write-Host "be used again unless the -savecred option is specified."
Write-Host
Write-Host "If a filename is not specified, the file vmexport.csv will be created in the current directory."
Write-Host
exit
}
$timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss"
$quiet = Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
if ($vCenter -eq "") {
$vCenter = Read-Host "Enter name of vCenter Server"
}
if ($SaveCred) {
$credential = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
$credential | Export-Clixml -path $env:USERPROFILE\kistools-$vcenter.cred
Write-Host "Saving credentials."
}
if (Test-Path -path $env:USERPROFILE\kistools-$vcenter.cred -PathType Leaf) {
$credentials = Import-Clixml -path $env:USERPROFILE\kistools-$vcenter.cred
Write-Host "Using stored credentials"
} else {
$credentials = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
if (!$credentials) {
Write-Host "ERROR: No credentials were entered" -foregroundcolor yellow
}
}
if (Test-Path -path $filename -PathType Leaf) {
Write-Host "File $filename already exists." -ForegroundColor Yellow
exit
}
try {
Write-Host -NoNewLine "Connecting to vCenter $vcenter..."
$vcconn = Connect-VIServer $vcenter -Credential $credentials -ErrorAction SilentlyContinue
Write-Host " Success" -ForegroundColor green
} catch {
Write-Host " Failure" -ForegroundColor Yellow -BackgroundColor Red
exit
}
if ($cluster -eq "") {
$Clusterlist = Get-Cluster | Sort-Object
While (($cluster -eq "") -or (-not $cluster)) {
Write-Host "`nCluster Selection:`n"
for ($x = 0; $x -lt $Clusterlist.length; $x++) {
Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($Clusterlist[$x].name)" -ForegroundColor Yellow
}
$Clusternum = Read-Host "`nSelect Cluster Number"
if ($Clusternum -as [int]) {
$Clusternum = [int]$Clusternum - 1
$cluster = $Clusterlist[$Clusternum]
}
}
$mycluster = get-cluster $cluster
} else {
$mycluster = get-cluster $cluster
}
# Collect base VMware Tools and Hardware version from first Host
$myhost = $mycluster | get-vmhost | select-object -first 1
$esxcli = Get-EsxCLI -VMHost $myhost -V2
$latestHW = ($myhost | Get-View).Capability.MaxSupportedVmVersion
$latestVMT = ($esxcli.software.vib.list.invoke() | Where-Object {$_.ID -match "VMware_locker_tools"}).Version
$latestHW
$latestVMT
exit
Write-Host "Gathering information about VMs in cluster $cluster..." -NoNewLine
$vmlist = $mycluster | get-vm
$vmcount = $vmlist.length
$vmresponse = @()
for ($x = 0; $x -lt $vmlist.length; $x++) {
$percent = [Math]::Round(($x / $vmlist.length) * 100,0)
Write-Progress -ID 1 -Activity "Collecting VM Information" -Status "Processing VM $($x+1) of $($vmlist.length)" -PercentComplete $percent
$thisvm = $vmlist[$x];
$thisvmguest = $thisvm | get-vmguest
$vmname = $thisvm.Name;
$vmhardwareversion = $thisvmguest.ExtensionData.HwVersion
$vmtoolsstatus = $thisvmguest.ExtensionData.ToolsRunningStatus
$vmtoolsversionstatus = $thisvmguest.ExtensionData.ToolsVersionStatus
$vmosname = $thisvmguest.OSFullName
$vmtoolsversion = $thisvmguest.ToolsVersion
$badvmnics = ($thisvm | get-NetworkAdapter | Where-Object {$_.Type -ne "Vmxnet3"}).length -gt 0
$thisvmobj = [PSCustomObject]@{
"Name" = $vmname
"VM Hardware Version" = $vmhardwareversion
"VMTools Status" = $vmtoolsstatus
"VMTools Version" = $vmtoolsversion
"VMTools Version Status" = $vmtoolsversionstatus
"Has Non vmxnet3 NICs" = $badvmnics
"VMHW Updated" = $null
"VMTools Updated" = $null
"In Prog" = ""
"Migrating" = ""
"Complete" = ""
}
$vmresponse += $thisvmobj
}
Write-Host "Disconnecting from vCenter $vcenter..." -NoNewLine
try {
$quiet = Disconnect-VIServer $vcenter -Confirm:$false
} catch {
Write-Host " FAILURE" -ForegroundColor Yellow - BackgroundColor Red
}
Write-Host " Success" -ForegroundColor Green
Write-Progress -ID 1 -Completed
Write-Host " Success" -ForegroundColor Green
Write-Host "Writing information about $($vmresponse.length) VMs to file $filename..." -NoNewLine
try {
$sheetTitle = "VM Export for Cluster $cluster - $timestamp"
if ($customer -ne "") {
$sheetTitle = "$customer - $sheetTitle"
}
$exceltable = $vmresponse | Export-Excel -path $filename -WorksheetName "vCenter VM Data" -PassThru -Autosize -FreezeTopRow `
-TableName "VMData" -TableStyle Medium15 -Title $sheetTitle -TitleBold -TitleSize 22 `
-TableTotalSettings @{ CPU = "Sum"; RAM = "Sum"; "Provisioned Storage" = "Sum"; "Used Space Original" = "Sum" }
} catch {
Write-Host
Write-Host "ERROR! Unable to create file $filename" -ForegroundColor Yellow
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red -BackgroundColor Yellow
}
try {
$sheet = $exceltable.Workbook.Worksheets["vCenter VM Data"]
$sheet.Column(3) | Set-ExcelRange -NFormat '#,##0 " GB"'
$sheet.Column(4) | Set-ExcelRange -NFormat '#,##0.00 " GB"'
$sheet.Column(5) | Set-ExcelRange -NFormat '#,##0.00 " GB"'
$sheet.Column(6) | Set-ExcelRange -NFormat '#,##0.00 " GB"'
Set-Format -Address $sheet.Cells["2:2"] -WrapText
$sheet.InsertColumn(1,1)
$sheet.Column(1).Width = 2
$sheet.Cells["I:R"].Style.HorizontalAlignment = "Center"
$sheet.Cells["C2:G2"].Style.HorizontalAlignment = "Center"
$sheet.Column(5).Width = 13
$sheet.Column(6).Width = 13
$sheet.Column(7).Width = 13
$sheet.Column(13).Width = 12
$sheet.Column(14).Width = 12
$sheet.Column(15).Width = 12
$sheet.Column(16).Width = 12
$sheet.Column(17).Width = 12
$sheet.Column(18).Width = 12
For ($counter = 3; $counter -lt 3 + $vmcount; ++$counter) {
$PFormula = '=IF(AND(COUNTIF(M' + $counter + ':O' + $counter + ',"X")<3,COUNTIF(M' + $counter + ':O' + $counter + ',"")<3),"X","")'
Set-ExcelRange -Address $sheet.Cells["P" + $counter] -Formula $PFormula
$QFormula = '=IF(OR(M' + $counter + '="O",N' + $counter + '="O",O' + $counter + '="O"),"X","")'
Set-ExcelRange -Address $sheet.Cells["Q" + $counter] -Formula $QFormula
$RFormula = '=IF(AND(M' + $counter + '="X",N' + $counter + '="X",O' + $counter + '="X"),"X","")'
Set-ExcelRange -Address $sheet.Cells["R" + $counter] -Formula $RFormula
$HFormula = '=if(AND($G' + $counter + '>0,$G' + $counter + '<>""), $F' + $counter + ',"")'
Set-ExcelRange -Address $sheet.Cells["H" + $counter] -Formula $HFormula
}
$datarange = "B3:R" + (2+$vmcount)
Add-ConditionalFormatting -Worksheet $sheet -Address $datarange -RuleType Expression -ConditionValue '=INDIRECT("VMData[@Disk Format]")="Thick"' -BackgroundColor Red -ForegroundColor White
Add-ConditionalFormatting -Worksheet $sheet -Address $datarange -RuleType Expression -ConditionValue '=INDIRECT("VMData[@Disk Format]")="O"' -BackgroundColor Orange
Add-ConditionalFormatting -Worksheet $sheet -Address $datarange -RuleType Expression -ConditionValue '=INDIRECT("VMData[@In Prog]")="X"' -BackgroundColor Yellow
Add-ConditionalFormatting -Worksheet $sheet -Address $datarange -RuleType Expression -ConditionValue '=INDIRECT("VMData[@Complete]")="X"' -BackgroundColor Green
$sheet.Cells["S4"].Value = "Total VMs:"
$sheet.Cells["S5"].Value = "Thick Provisioned:"
$sheet.Cells["S6"].Value = "Converting to Thin:"
$sheet.Cells["S7"].Value = "Partially Migrated:"
$sheet.Cells["S8"].Value = "In Progress:"
$sheet.Cells["S9"].Value = "Completed:"
$sheet.Cells["S10"].Value = "Remaining:"
$sheet.Cells["S12"].Value = "Original Space Usage:"
$sheet.Cells["S13"].Value = "New Space Usage:"
$sheet.Cells["S14"].Value = "Space Saved:"
$sheet.Cells["S15"].Value = "Savings:"
$sheet.Cells["S4:S15"].Style.HorizontalAlignment = "Right"
$sheet.Column(19).Width = 22
Set-ExcelRange -Address $sheet.Cells["T4"] -Formula '=COUNTA(VMData[Name])'
Set-ExcelRange -Address $sheet.Cells["T5"] -Formula '=COUNTIF(VMData[Disk Format], "<>Thin")'
Set-ExcelRange -Address $sheet.Cells["T6"] -Formula '=COUNTIF(VMData[Disk Format], "O")'
Set-ExcelRange -Address $sheet.Cells["T7"] -Formula '=COUNTIF(VMData[Migrating],"X")'
Set-ExcelRange -Address $sheet.Cells["T8"] -Formula '=COUNTIF(VMData[In Prog], "X")'
Set-ExcelRange -Address $sheet.Cells["T9"] -Formula '=COUNTIF(VMData[Complete], "X")'
Set-ExcelRange -Address $sheet.Cells["T10"] -Formula '=T4-T9'
$formula = '=SUM(H3:H' + (2+$vmcount) +')'
Set-ExcelRange -Address $sheet.Cells["T12"] -Formula $formula
Set-ExcelRange -Address $sheet.Cells["T12"] -NFormat '#,##0.00 " GB"'
Set-ExcelRange -Address $sheet.Cells["T13"] -Formula '=SUM(VMData[Used Space Now])'
Set-ExcelRange -Address $sheet.Cells["T13"] -NFormat '#,##0.00 " GB"'
Set-ExcelRange -Address $sheet.Cells["T14"] -Formula '=T12-T13'
Set-ExcelRange -Address $sheet.Cells["T14"] -NFormat '#,##0.00 " GB"'
Set-ExcelRange -Address $sheet.Cells["T15"] -Formula '=IF(T12>0,T14/T12,"")'
Set-ExcelRange -Address $sheet.Cells["T15"] -NFormat '#.00%'
$sheet.Column(8).Hidden = $true
$sheet.Column(20).Width = 14
} catch {
Write-Host
Write-Host "ERROR! Unable to create file $filename" -ForegroundColor Yellow
Write-Host "Error: $($_.Exception.Message)" -ForegroundColor Red -BackgroundColor Yellow
try {
Close-ExcelPackage $exceltable
Remove-Item $filename
Remove-Item $filename
} catch {
Remove-Item $filename
Remove-Item $filename
}
}
$exceltable.Workbook.WorkSheets[1].Tables["VMData"].ShowFilter = $false
Close-ExcelPackage $exceltable
Disconnect-V
Write-Host " Success" -ForegroundColor Green
+317
View File
@@ -0,0 +1,317 @@
param (
[string]$vCenter = "",
[string]$VMHost = "",
[string]$Test1Vmk = "",
[string]$Test1Host = "",
[int]$Test1Frame = 0,
[string]$Test2Vmk = "",
[string]$Test2Host = "",
[int]$Test2Frame = 0,
[int]$Count = 0,
[switch]$SaveCred = $false,
[switch]$Help = $false
)
<# Write-Host "vCenter - $vCenter"
Write-Host "VMHost - $VMHost"
Write-Host "Test1VMK - $Test1Vmk"
Write-Host "Test1Host - $Test1Host"
Write-Host "Test1Frame - $Test1Frame"
Write-Host "Test2VMK - $Test2Vmk"
Write-Host "Test2Host - $Test2Host"
Write-Host "Test2Frame - $Test2Frame"
Write-Host "Count - $Count"
Write-Host "SaveCred - $SaveCred"#>
# Variables
$fileVersion = "1.3.2"
$fileDate = "2023-04-16"
# Display Script Banner
Write-Host "--------------------------------------------------" -ForegroundColor White
Write-Host "Host Mulitple Concurrent VMK Ping Script" -ForegroundColor Green
Write-Host "Version $($FileVersion) ($($FileDate))" -ForegroundColor Green
Write-Host "Written by Charlie Silverman" -ForegroundColor Green
Write-Host "--------------------------------------------------" -ForegroundColor White
if ($Help) {
Write-Host
Write-Host "Purpose: Perform multiple ping tests simultaneously from an ESXi host."
Write-Host "Command Syntax:"
Write-Host " HostMultiPingTest.ps1 (-vcenter [vcenter host name]) (-VMHost ""[host]"") (-Test1Host ""[ipaddress]"")" -foregroundcolor green
Write-Host " (-Test1VMK ""[vmkPort]"") (-Test1Frame [framesize]) (-Test2Host ""[ipaddress]"") (-Test2VMK ""[vmkPort]"")" -foregroundcolor green
Write-Host " (-Test2Frame [framesize]) (-count [count]) (-savecred) (-help)`n" -foregroundcolor green
Write-Host "Command Line Options:"
Write-Host
Write-Host -NoNewLine " -vCenter " -foregroundcolor Green
Write-Host "- The FQDN or IP address of a vCenter server."
Write-Host -NoNewLine " -VMHost " -foregroundcolor Green
Write-Host "- The name of the host as shown in vCenter."
Write-Host -NoNewLine " -Test1Host " -foregroundcolor Green
Write-Host "- The IP address of the system to ping for test 1."
Write-Host -NoNewLine " -Test1Vmk " -foregroundcolor Green
Write-Host "- The VMkernel port on the host to ping for test 1."
Write-Host -NoNewLine " -Test1Frame " -foregroundcolor Green
Write-Host "- The TCP frame size to use for test 1. Default: 1500."
Write-Host -NoNewLine " -Test2Host " -foregroundcolor Green
Write-Host "- The IP address of the system to ping for test 2."
Write-Host -NoNewLine " -Test2Vmk " -foregroundcolor Green
Write-Host "- The VMkernel port on the host to ping for test 2."
Write-Host -NoNewLine " -Test2Frame " -foregroundcolor Green
Write-Host "- The TCP frame size to use for test 2. Default: 1500."
Write-Host -NoNewLine " -count " -foregroundcolor Green
Write-Host "- The number of ping tests to run. Default: unlimited."
Write-Host -NoNewLine " -savecred " -foregroundcolor Green
Write-Host "- Configure and store vCenter server credentials. This will only store the credentials under"
Write-Host " the current logged in user."
Write-Host -NoNewLine " -help " -foregroundcolor Green
Write-Host "- Display command help."
Write-Host
Write-Host "If no any of the information is not provided, you will be prompted. If a credential has been previously stored, it will be used again"
Write-Host "unless the -savecred option is specified."
Write-Host
exit
}
$quiet = Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
if ($vCenter -eq "") {
$vCenter = Read-Host "Enter name of vCenter Server"
}
if ($SaveCred) {
$credential = Get-Credential -Message "Enter credentials for vCenter server $vCenter x"
$credential | Export-Clixml -path $env:USERPROFILE\kispingtest-$vcenter.cred
Write-Host "Saving credentials."
}
if (Test-Path -path $env:USERPROFILE\kispingtest-$vcenter.cred -PathType Leaf) {
$credentials = Import-Clixml -path $env:USERPROFILE\kispingtest-$vcenter.cred
Write-Host "Using stored credentials"
} else {
$credentials = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
if (!$credentials) {
Write-Host "ERROR: No credentials were entered" -foregroundcolor yellow
}
}
try {
Write-Host -NoNewLine "Connecting to vCenter $vcenter..."
$vcconn = Connect-VIServer $vcenter -Credential $credentials -ErrorAction SilentlyContinue
Write-Host " Success" -ForegroundColor green
} catch {
Write-Host " Failure" -ForegroundColor Yellow -BackgroundColor Red
exit
}
if ($VMHost -eq "") {
$VMHostlist = Get-VMHost | Sort-Object
While (($VMHost -eq "") -or (-not $VMHost)) {
Write-Host "`nHost Selection:`n"
for ($x = 0; $x -lt $VMHostlist.length; $x++) {
Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($VMHostlist[$x].name)" -ForegroundColor Yellow
}
$VMHostnum = Read-Host "`nSelect Host Number"
$VMHostnum = [int]$VMHostnum - 1
$VMHost = $VMHostlist[$VMHostnum]
}
$myhost = get-vmhost $VMHost
} else {
$myhost = get-vmhost $VMHost
}
$vmks = $myhost | Get-VMHostNetworkAdapter | Where-Object {$_.Name -like "vmk*"} | Sort-Object Name
While (($Test1Vmk -eq "") -or (-not $Test1Vmk)) {
Write-Host "`nVMKernel Port 1 Selection:`n"
for ($x = 0; $x -lt $vmks.length; $x++) {
$myvmk1 = $vmks[$x];
$mask = [ipaddress]$myvmk1.SubnetMask
$binary = [convert]::ToString($mask.Address, 2)
$mask_length = ($binary -replace 0,$null).Length
Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($myvmk1.Name) ($($myvmk1.IP)/$($mask_length))" -ForegroundColor Yellow
}
$vmknum = Read-Host "`nSelect VMKernel Port Number for Test 1"
$Test1Vmk = $vmks[$vmknum - 1].Name
$myvmk1 = $vmks[$vmknum - 1]
}
if ((-not(Test-Path variable:myvmk1) -or ($myvmk1 -ne $null))) {
$myvmk1 = $myhost | Get-VMHostNetworkAdapter | Where-Object {$_.Name -like "$Test1Vmk"}
$mask = [ipaddress]$myvmk1.SubnetMask
$binary = [convert]::ToString($mask.Address, 2)
$mask_length = ($binary -replace 0,$null).Length
Write-Host "Using $($myvmk1.Name) - $($myvmk.PortGroupName) ($($myvmk1.IP)/$($mask_length)) for Test 1"
}
$vmk1testvalid = $false
while (-not $vmk1testvalid) {
if ($Test1Host -ne "") {
$thisip = [ipaddress]$Test1Host
$subnet = [ipaddress]$myvmk1.IP
$netmask = [ipaddress]$myvmk1.SubnetMask
$ipbits = [int[]]$($myvmk1.IP).split('.')
$maskbits = [int[]]$($myvmk1.SubnetMask).split('.')
$networkidbits = 0..3 | ForEach-Object { $ipbits[$_] -band $maskbits[$_] }
$networkid = [ipaddress]($networkidbits -join '.')
If ($networkid.Address -eq ($thisip.Address -band $netmask.Address)) {
$vmk1testvalid = $true
} else {
Write-Host "Error: IP Address is outside the allowed subnet." -ForegroundColor Red
$Test1Host = Read-Host "Enter IP Address to ping for Test 1"
}
} else {
$Test1Host = Read-Host "Enter IP Address to ping for Test 1"
}
}
While ( (-not ($Test1Frame -is [int]) -or ($Test1Frame -lt 1500) ) ) {
if ($Test1Frame -eq 0) {
$Test1Frame = Read-Host "`nFrame size for Test 1 (1500)"
if (!($Test1Frame -is [int]) -or ($Test1Frame -lt 1500)) { $Test1Frame = 1500 }
}
}
While (($Test2Vmk -eq "") -or (-not $Test2Vmk)) {
Write-Host "`nVMKernel Port 2 Selection:`n"
for ($x = 0; $x -lt $vmks.length; $x++) {
$myvmk2 = $vmks[$x]
if ($myvmk2.Name.substring(0,3) -ne "vmk") {
continue
}
$mask = [ipaddress]$myvmk2.SubnetMask
$binary = [convert]::ToString($mask.Address, 2)
$mask_length = ($binary -replace 0,$null).Length
Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($myvmk2.Name) - $($myvmk.PortGroupName) ($($myvmk2.IP)/$($mask_length))" -ForegroundColor Yellow
}
$vmknum = Read-Host "`nSelect VMKernel Port Number for Test 2"
$Test2Vmk = $vmks[$vmknum - 1].Name
$myvmk2 = $vmks[$vmknum - 1]
}
if ((-not(Test-Path variable:myvmk2) -or ($myvmk2 -ne $null))) {
$myvmk2 = $myhost | Get-VMHostNetworkAdapter | Where-Object {$_.Name -like "$Test2Vmk"}
$mask = [ipaddress]$myvmk2.SubnetMask
$binary = [convert]::ToString($mask.Address, 2)
$mask_length = ($binary -replace 0,$null).Length
Write-Host "Using $($myvmk2.Name) ($($myvmk2.IP)/$($mask_length)) for Test 2"
}
$vmk2testvalid = $false
while (-not $vmk2testvalid) {
if (($Test2Host -ne "") -and $Test2Host) {
$thisip = [ipaddress]$Test2Host
$subnet = [ipaddress]$myvmk2.IP
$netmask = [ipaddress]$myvmk2.SubnetMask
$ipbits = [int[]]$($myvmk2.IP).split('.')
$maskbits = [int[]]$($myvmk2.SubnetMask).split('.')
$networkidbits = 0..3 | ForEach-Object { $ipbits[$_] -band $maskbits[$_] }
$networkid = [ipaddress]($networkidbits -join '.')
If ($networkid.Address -eq ($thisip.Address -band $netmask.Address)) {
$vmk2testvalid = $true
} else {
Write-Host "Error: IP Address is outside the allowed subnet." -ForegroundColor Red
$Test2Host = Read-Host "Enter IP Address to ping for Test 2"
}
} else {
$Test2Host = Read-Host "Enter IP Address to ping for Test 2"
}
}
While ( (-not ($Test2Frame -is [int]) -or ($Test2Frame -lt 1500) ) ) {
if ($Test2Frame -eq 0) {
$Test2Frame = Read-Host "`nFrame size for Test 2 (1500)"
if (!($Test2Frame -is [int]) -or ($Test2Frame -lt 1500)) { $Test2Frame = 1500 }
}
}
Write-host "`nBegin Testing:"
$esxcli = get-esxcli -vmhost (get-vmhost $myhost) -v2
$params1 = (get-esxcli -v2 -vmhost (get-vmhost $myhost)).network.diag.ping.CreateArgs()
$params2 = (get-esxcli -v2 -vmhost (get-vmhost $myhost)).network.diag.ping.CreateArgs()
$params1.host = $Test1Host
$params1.interface = $Test1Vmk
$params1.size = $Test1Frame
$params1.count = 1
$params2.host = $Test2Host
$params2.interface = $Test2Vmk
$params2.size = $Test2Frame
$params2.count = 1
$counter = 0
$test1passcount = 0
$test2passcount = 0
try {
while (($counter -lt $Count) -or ($Count -eq 0)) {
$counter += 1
$result1 = ($esxcli.network.diag.ping.Invoke($params1)).summary
$result2 = ($esxcli.network.diag.ping.Invoke($params2)).summary
$part1 = $Test1Vmk + "->" + $result1.HostAddr + "(" + $Test1Frame + ") "
if ($result1.Received -eq 1) {
$test1 = "Good"
++$test1passcount
} else {
$test1 = "Bad"
}
$part2 = $Test2Vmk + "->" + $result2.HostAddr + "(" + $Test2Frame + ") "
if ($result2.Received -eq 1) {
$test2 = "Good"
++$test2passcount
} else {
$test2 = "Bad"
}
Write-Host "$(([string]$counter).PadLeft(4,' ')): $($VMHost): $part1" -NoNewLine
If ($test1 -eq "Good") {
Write-Host "$test1" -NoNewLine -ForegroundColor Green
} else {
Write-Host "$test1" -NoNewLine -ForegroundColor Red
}
Write-Host " $part2" -NoNewLine
If ($test2 -eq "Good") {
Write-Host "$test2" -ForegroundColor Green
} else {
Write-Host "$test2" -ForegroundColor Red
}
Start-Sleep -seconds 1
}
} finally {
if ($counter -ne $Count) {
Write-Host "`n--- Script processing cancelled." -ForegroundColor Red
}
Write-Host "`n------------------------------------------------"
Write-Host "Results:"
Write-Host "From: " -NoNewLine
Write-Host $VMHost -ForegroundColor Yellow
Write-Host "Count: " -NoNewLine
Write-Host $counter -ForegroundColor Yellow
Write-Host "`nTest 1:"
Write-Host "VMKernel port: " -NoNewLine
Write-Host $Test1Vmk -ForegroundColor Yellow
Write-Host "Destination: " -NoNewLine
Write-Host $Test1Host -ForegroundColor Yellow
Write-Host "Frame Size: " -NoNewLine
Write-Host $Test1Frame -ForegroundColor Yellow
Write-Host "Success: " -NoNewLine
Write-Host $test1passcount -ForegroundColor Green -NoNewLine
Write-Host " - Failure: " -NoNewLine
Write-Host ($counter - $test1passcount) -ForegroundColor Red
Write-Host "`nTest 2:"
Write-Host "VMKernel port: " -NoNewLine
Write-Host $Test2Vmk -ForegroundColor Yellow
Write-Host "Destination: " -NoNewLine
Write-Host $Test2Host -ForegroundColor Yellow
Write-Host "Frame Size: " -NoNewLine
Write-Host $Test2Frame -ForegroundColor Yellow
Write-Host "Success: " -NoNewLine
Write-Host $test2passcount -ForegroundColor Green -NoNewLine
Write-Host " - Failure: " -NoNewLine
Write-Host ($counter - $test2passcount) -ForegroundColor Red
}
+183
View File
@@ -0,0 +1,183 @@
param (
[string]$vCenter = "",
[string]$cluster = "",
[string]$VmHost = "",
[string]$vmkPort = "",
[int]$testFrame = 1472,
[switch]$SaveCred = $false,
[switch]$Help = $false
)
# Variables
$fileVersion = "1.2.6"
$fileDate = "2025-09-15"
# Display Script Banner
Write-Host "--------------------------------------------------" -ForegroundColor White
Write-Host "Host Network Testing Script" -ForegroundColor Green
Write-Host "Version $($FileVersion) ($($FileDate))" -ForegroundColor Green
Write-Host "Written by Charlie Silverman" -ForegroundColor Green
Write-Host "--------------------------------------------------" -ForegroundColor White
if ($Help) {
Write-Host
Write-Host "Purpose: Perform multiple ping tests simultaneously from an ESXi host."
Write-Host "Command Syntax:"
Write-Host " NetworkTester.ps1 (-vcenter [vcenter host name]) (-cluster ""[cluster]"") (-VmHost ""[host]"") (-vmkPort ""[vmkPort]"")" -foregroundcolor green
Write-Host " (-testFrame [framesize]) (-savecred) (-help)`n" -foregroundcolor green
Write-Host "Command Line Options:"
Write-Host
Write-Host -NoNewLine " -vCenter " -foregroundcolor Green
Write-Host "- The FQDN or IP address of a vCenter server."
Write-Host -NoNewLine " -cluster " -foregroundcolor Green
Write-Host "- The name of the cluster as shown in vCenter."
Write-Host -NoNewLine " -VmHost " -foregroundcolor Green
Write-Host "- [Optional] The name of a host to test. If not specified, all hosts in the cluster will be tested."
Write-Host -NoNewLine " -vmkPort " -foregroundcolor Green
Write-Host "- The VMkernel port on the host to test."
Write-Host -NoNewLine " -testFrame " -foregroundcolor Green
Write-Host "- The TCP frame size to use for the test. Default: 1500."
Write-Host -NoNewLine " -savecred " -foregroundcolor Green
Write-Host "- Configure and store vCenter server credentials. This will only store the credentials under"
Write-Host " the current logged in user."
Write-Host -NoNewLine " -help " -foregroundcolor Green
Write-Host "- Display command help."
Write-Host
Write-Host "If any of the information is not provided, you will be prompted. If a credential has been previously stored, it will"
Write-Host "be used again unless the -savecred option is specified."
Write-Host
Write-Host "Each host in the selected cluster will perform ping tests to all IP addresses assigned to the selected vmKernel port"
Write-Host "on all hosts in the cluster."
Write-Host
exit
}
$quiet = Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
if ($vCenter -eq "") {
$vCenter = Read-Host "Enter name of vCenter Server"
}
if ($SaveCred) {
$credential = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
$credential | Export-Clixml -path $env:USERPROFILE\kispingtest-$vcenter.cred
Write-Host "Saving credentials."
}
if (Test-Path -path $env:USERPROFILE\kispingtest-$vcenter.cred -PathType Leaf) {
$credentials = Import-Clixml -path $env:USERPROFILE\kispingtest-$vcenter.cred
Write-Host "Using stored credentials"
} else {
$credentials = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
if (!$credentials) {
Write-Host "ERROR: No credentials were entered" -foregroundcolor yellow
}
}
try {
Write-Host -NoNewLine "Connecting to vCenter $vcenter..."
$vcconn = Connect-VIServer $vcenter -Credential $credentials -ErrorAction SilentlyContinue
Write-Host " Success" -ForegroundColor green
} catch {
Write-Host " Failure" -ForegroundColor Yellow -BackgroundColor Red
exit
}
if ($cluster -eq "") {
$Clusterlist = Get-Cluster | Sort-Object
While (($cluster -eq "") -or (-not $cluster)) {
Write-Host "`nCluster Selection:`n"
for ($x = 0; $x -lt $Clusterlist.length; $x++) {
Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($Clusterlist[$x].name)" -ForegroundColor Yellow
}
$Clusternum = Read-Host "`nSelect Cluster Number"
$Clusternum = [int]$Clusternum - 1
$cluster = $Clusterlist[$Clusternum]
}
$mycluster = get-cluster $cluster
} else {
$mycluster = get-cluster $cluster
}
$firsthost = $mycluster | Get-VMHost | Select-Object -first 1
$vmks = $firsthost | Get-VMHostNetworkAdapter | Where-Object {$_.Name -like "vmk*"} | Sort-Object Name
While (($vmkPort -eq "") -or (-not $vmkPort)) {
Write-Host "`nVMKernel Port Selection:`n"
for ($x = 0; $x -lt $vmks.length; $x++) {
$myvmk = $vmks[$x];
$mask = [ipaddress]$myvmk.SubnetMask
$binary = [convert]::ToString($mask.Address, 2)
$mask_length = ($binary -replace 0,$null).Length
Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($myvmk.Name) - $($myvmk.PortGroupName) ($($myvmk.IP)/$($mask_length))" -ForegroundColor Yellow
}
$vmknum = Read-Host "`nSelect VMKernel Port Number for Testing"
$vmkPort = $vmks[$vmknum - 1].Name
$myvmk = $vmks[$vmknum - 1]
}
if ((-not(Test-Path variable:myvmk) -or ($myvmk -ne $null))) {
$myvmk = $firsthost | Get-VMHostNetworkAdapter | Where-Object {$_.Name -like "$vmkPort"}
$mask = [ipaddress]$myvmk.SubnetMask
$binary = [convert]::ToString($mask.Address, 2)
$mask_length = ($binary -replace 0,$null).Length
Write-Host "Using $($myvmk.Name) ($($myvmk.PortGroupName)) for Testing"
}
$targetlist = get-cluster $mycluster | get-vmhost | Get-VMHostNetworkAdapter | Where-Object {$_.Name -like "$myvmk"} | Select-Object -Property IP | Sort-Object IP
if ($VmHost -ne "") {
try {
$hostlist = Get-VMhost $VmHost -ErrorAction Stop
} catch {
Write-Host "ERROR - Host $VmHost not found." -ForegroundColor Yellow -BackgroundColor Red
exit*
}
if ($hostlist[0].parent.name -ne $cluster) {
Write-Host "ERROR - Host $VmHost not part of cluster $cluster" -ForegroundColor Yellow -BackgroundColor Red
exit
}
} else {
$hostlist = $mycluster | Get-VMHost | Sort-Object Name
}
for ($x = 0; $x -lt $hostlist.length; $x++) {
$myhost = $hostlist[$x]
$myip = $myhost | Get-VMHostNetworkAdapter | Where-Object {$_.Name -like "$myvmk"} | Select-Object -Property IP
$hostname = $myhost.name
$tcpstack = $myvmk.ExtensionData.Spec.NetStackInstanceKey
Write-Host "Testing Host $hostname on $($myvmk.PortGroupName) with a frame size of $testFrame ($myip)"
$esxcli = get-esxcli -vmhost (get-vmhost $myhost) -v2
for ($y = 0; $y -lt $targetlist.length; $y++) {
$params = (get-esxcli -v2 -vmhost (get-vmhost $myhost)).network.diag.ping.CreateArgs()
$params.host = $targetlist[$y].IP
$params.interface = $vmkPort
$params.size = $testFrame
$params.df = $true
$params.count = 1
if ($tcpstack -ne "defaultTcpipStack") {
$params.netstack = $tcpstack
}
$result = ($esxcli.network.diag.ping.Invoke($params)).summary
$response = $vmkPort + "->" + $result.HostAddr + "(" + $testFrame + ") "
if ($result.Received -gt 0) {
$test = "Good"
} else {
$test = "Bad"
}
Write-Host " - $($hostname): $response" -NoNewLine
If ($test -eq "Good") {
Write-Host "$test" -ForegroundColor Green
} else {
Write-Host "$test" -ForegroundColor Red
}
}
}
Disconnect-VIServer $vCenter -confirm:$false
+142
View File
@@ -0,0 +1,142 @@
#requires -Modules posh-ssh
param (
[string]$vCenter = "",
[string]$Cluster = "",
[string]$Command = "",
[switch]$SaveCred = $false,
[switch]$Help = $false
)
# Variables
$FileVersion = "1.0.1"
$FileDate = "2026-04-18"
# Display Script Banner
Write-Host "--------------------------------------------------" -ForegroundColor White
Write-Host "Run ESXi CLI Command" -ForegroundColor Green
Write-Host "Version $($FileVersion) ($($FileDate))" -ForegroundColor Green
Write-Host "Written by Charlie Silverman" -ForegroundColor Green
Write-Host "--------------------------------------------------" -ForegroundColor White
if ($Help) {
Write-Host
Write-Host "Purpose: Run a CLI command on all hosts in a cluster."
Write-Host "Command Syntax:"
Write-Host " RunESXiCommand.ps1 (-vCenter [vcenter host name]) (-Cluster ""[cluster]"") (-Command ""[command]"") (-savecred)" -foregroundcolor green
Write-Host " (-NovCenter) (-savecred) (-help)`n" -foregroundcolor green
Write-Host "Command Line Options:"
Write-Host
Write-Host -NoNewLine " -vCenter " -foregroundcolor Green
Write-Host "- The FQDN or IP address of a vCenter server."
Write-Host -NoNewLine " -Cluster " -foregroundcolor Green
Write-Host "- The name of the cluster as shown in vCenter."
Write-Host -NoNewLine " -Command " -foregroundcolor Green
Write-Host "- The full CLI command to run on each host."
Write-Host -NoNewLine " -Savecred " -foregroundcolor Green
Write-Host "- Configure and store vCenter server credentials. This will only store the credentials under"
Write-Host " the current logged in user."
Write-Host -NoNewLine " -help " -foregroundcolor Green
Write-Host "- Display command help."
Write-Host
Write-Host "If any of the information is not provided, you will be prompted. If a credential has been previously stored, it will"
Write-Host "be used again unless the -savecred option is specified."
exit
}
$quiet = Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
if ($vCenter -eq "") {
$vCenter = Read-Host "Enter name of vCenter Server"
}
if ($SaveCred) {
$credential = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
$credential | Export-Clixml -path $env:USERPROFILE\kistools-$vcenter.cred
Write-Host "Saving vCenter credentials."
$credential = Get-Credential -Message "Enter credentials for ESXi hosts in $vCenter"
$credential | Export-Clixml -path $env:USERPROFILE\kistools-$vcenter-esxi.cred
Write-Host "Saving ESXi credentials."
}
if (Test-Path -path $env:USERPROFILE\kistools-$vcenter.cred -PathType Leaf) {
$credentials = Import-Clixml -path $env:USERPROFILE\kistools-$vcenter.cred
Write-Host "Using stored vCenter credentials"
} else {
$credentials = Get-Credential -Message "Enter credentials for vCenter server $vCenter"
if (!$credentials) {
Write-Host "ERROR: No credentials were entered" -foregroundcolor yellow
}
}
if (Test-Path -path $env:USERPROFILE\kistools-$vcenter-esxi.cred -PathType Leaf) {
$credentials_ssh = Import-Clixml -path $env:USERPROFILE\kistools-$vcenter-esxi.cred
Write-Host "Using stored ESXi credentials"
} else {
$credentials_ssh = Get-Credential -Message "Enter credentials for ESXi hosts in $vCenter"
if (!$credentials) {
Write-Host "ERROR: No credentials were entered" -foregroundcolor yellow
}
}
try {
Write-Host -NoNewLine "Connecting to vCenter $vcenter..."
$vcconn = Connect-VIServer $vcenter -Credential $credentials -ErrorAction SilentlyContinue
$test = get-cluster
Write-Host " Success" -ForegroundColor green
} catch {
Write-Host " Failure" -ForegroundColor Yellow -BackgroundColor Red
Write-Host "Error: $($_.Exception.Message)"
exit
}
if ($cluster -eq "") {
$Clusterlist = Get-Cluster | Sort-Object
While (($cluster -eq "") -or (-not $cluster)) {
Write-Host "`nCluster Selection:`n"
for ($x = 0; $x -lt $Clusterlist.length; $x++) {
Write-Host "$(([string]($x+1)).PadLeft(3,' '))" -NoNewLine -ForegroundColor Green
Write-Host ": " -NoNewLine -ForegroundColor Gray
Write-Host "$($Clusterlist[$x].name)" -ForegroundColor Yellow
}
$Clusternum = Read-Host "`nSelect Cluster Number"
$Clusternum = [int]$Clusternum - 1
$cluster = $Clusterlist[$Clusternum]
}
$mycluster = get-cluster $cluster
} else {
$mycluster = get-cluster $cluster
}
if ($Command -eq "") {
$Command = Read-Host "Enter CLI Command to run on each host"
}
$myhosts = $mycluster | Get-VMHost | Sort-Object -Property Name
foreach($myhost in $myhosts) {
$myssh = $myhost | Get-VMHostService | Where-Object {$_.Key -eq "TSM-SSH"}
if (!$myssh.Running) {
Write-Host "-- Starting SSH Service on Host $($myhost.Name)"
$quiet = $myssh | Start-VMHostService -Confirm:$false
}
$sshsession = New-SSHSession -ComputerName $myhost.Name -Credential $credentials_ssh -AcceptKey -KeepAliveInterval 5
Write-Host "-- Running command " -NoNewLine
Write-Host "$Command" -NoNewLine -ForegroundColor yellow
Write-Host " on host " -NoNewLine
Write-Host "$myhost" -ForegroundColor yellow
$result = Invoke-SSHCommand -SessionID $sshsession.SessionId -Command $Command -Timeout 30
Write-Host "Command Output:"
$result.Output
Write-Host "Exit Status: $($result.ExitStatus)"
$quiet = Remove-SSHSession -SessionID $sshsession.SessionId
if (!$myssh.Running) {
Write-Host "-- Stoppnig SSH Service on Host $($myhost.Name)"
$quiet = $myssh | Stop-VMHostService -Confirm:$false
}
Write-Host "----------------------------"
}