#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 "----------------------------" }