Adding scripts
This commit is contained in:
1 parent
e78eed48b6
commit
fc7cfeb008
10 files changed
+2321
No files matched your search
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
@@ -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
|
||||
@@ -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."
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -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 "----------------------------"
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user