VMware Cloud Community
amirpfpa
Contributor
Contributor
Jump to solution

List Certificate Details from Hosts using PowerCLI

I am using Powercli from Powershell. Looking to list the details of all the hosts certificates connected to the VCSA. The command "get-vmhost" will list all the hosts connected to the Vcsa. Looking particularly to list the "issuer" of the certificates for all the hosts. Any tips would be nice. This information can be obtained from the Web client by going to each hosts and then checking the certificate "issuer" for each host. We have a large environment. Looking forward to a powercli script that can accomplish this in one go. 

Reply
0 Kudos
2 Solutions

Accepted Solutions
LucD
Leadership
Leadership
Jump to solution

You mean something like this?

PS: are you going to reply to this thread, contrary to your other thread from 2 weeks ago?

Get-VMHost  -PipelineVariable esx |
ForEach-Object -Process {
  $certMgr = Get-View -Id $esx.ExtensionData.ConfigManager.CertificateManager
  New-Object -TypeName PSObject -Property ([ordered]@{
    VMHost = $esx.Name
    CertIssuer = $certMgr.CertificateInfo.Issuer
    CertSubject = $certMgr.CertificateInfo.Subject
    CertExpiration = $certMgr.CertificateInfo.NotAfter
    CertStatus = $certMgr.CertificateInfo.Status
  })
} | Format-List

 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

LucD
Leadership
Leadership
Jump to solution

Replace Format-List with

Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

Reply
0 Kudos
10 Replies
LucD
Leadership
Leadership
Jump to solution

You mean something like this?

PS: are you going to reply to this thread, contrary to your other thread from 2 weeks ago?

Get-VMHost  -PipelineVariable esx |
ForEach-Object -Process {
  $certMgr = Get-View -Id $esx.ExtensionData.ConfigManager.CertificateManager
  New-Object -TypeName PSObject -Property ([ordered]@{
    VMHost = $esx.Name
    CertIssuer = $certMgr.CertificateInfo.Issuer
    CertSubject = $certMgr.CertificateInfo.Subject
    CertExpiration = $certMgr.CertificateInfo.NotAfter
    CertStatus = $certMgr.CertificateInfo.Status
  })
} | Format-List

 


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

amirpfpa
Contributor
Contributor
Jump to solution

Thanks a lot for assisting. Exactly what I was looking for. Kindly can you please update it so the output goes to a cvs, excel... file. Much Thanks...
Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Replace Format-List with

Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
amirpfpa
Contributor
Contributor
Jump to solution

You awesome dude...
New here. You can close the thread if you like. 

Reply
0 Kudos
system_noida
Enthusiast
Enthusiast
Jump to solution

Hi @LucD ,

I wanted to add this certificate list into my daily health check report code, please could you help me . Below is my daily health check report code.

## Script Paramaters

$VCServer = 'VCenter01'
$SMTPServer = 'SMTP01.testlab.com'
$toAddress = 'jk@testlab.com'
$FromAddress = 'jk@testlab.com'
$ReportExport = 'F:\JK\vMware-Daily-HealtchCheck\'
$date = Get-Date -f "yyyy-MM-dd_HH.mm.ss"
$subject = "VMWare Daily Health Report | $VCServer"

## Script Variables
$snapshotdays = "10"
$Snapshotdate = (Get-Date).AddDays(-$snapshotdays)
$VCEventDate = (Get-Date).AddDays(-1)
$datastorePrecFree = "20"

## Clear VMware Tools Variable
$VMwareToolsReport = ""

## Function to check for export directory and create directory if does not exist.
function CreateDirectory {
$folderCheck = Test-Path -Path "$ReportExport"
if ($folderCheck -eq $false) {
Write-Warning $dlfolder "not found, creating it."
New-Item $dlfolder -type directory
}
}
CreateDirectory | Out-Null

## Add Vmware Powershell Module
Add-PSsnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue -ErrorVariable ProcessError;
if ($processerror) {
Write-Warning "PSsnapin is not avaliable. Will load VMware powercli PS Module"
Import-Module -Name VMware.VimAutomation.Core
}

## VCenter Connection
$VCStatus = connect-VIServer $VCServer -ErrorAction SilentlyContinue -ErrorVariable ErrorProcess;
if($ErrorProcess){
Write-Warning "Error connecting to vCenter Server $VCServer error message below"
Write-Warning $Error[0].Exception.Message
$Error[0].Exception.Message | Out-File $ReportExport\ConnectionError.txt
exit
}

else
{

## Heading
$Heading = "<h1>VMware Daily Report</h1>"

## HTML Formating
$HTMLFormat = @"
<style>
body {background-color: #9ab2c7;font-family: Arial; font-size: 14pt;}
h1 {color: #080D07; text-align: center;font-size: 40px;display: block;font-family: "Arial Black", Times, serif;}
h2 {color: #080D07; font-family: "Arial Black"}
TABLE{border-style: solid;border-color: black;}
TH{border-style: solid;border-color: Black;background-color: #4682B4;}
TD{background-color:#DCDCDC}
table {
border-collapse: collapse;width: 100%;
}
table, th, td {
border: 4px solid black;height: 25px;text-align: Center;font-weight: bold;
}
</style>
"@

## Vcenter Connection Test
Write-Host "Checking vCenter Connection" -ForegroundColor Green
if($VCStatus.IsConnected -eq $true){

$VCConnect = $VCStatus | Select-Object Name,@{N="Vcenter Server Available";E={$VCStatus.IsConnected}},Port,version |
ConvertTo-HTML -Fragment -PreContent "<h2>vCenter PowerShell Response</h2>"
}
Else
{
$VCConnect = "<h2>vCenter PowerShell Response</h2>" + "Cannot Connect to $($VCStatus.Name)"
}

## Check Vcenter Web Client
$VCName = $VCStatus.Name
$VCURL = "HTTPS://$VCName/ui"

## Exclude SSL check for Invoke web request
add-type @"
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
"@

[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
try {$VCWebCheck = Invoke-WebRequest -Uri $VCURL -UseBasicParsing} catch {
$ErrorException = $_.Exception
$ErrorResponse = $_.Exception.Response}
if ($VCWebCheck.StatusCode -eq "200") {
$VCResponseStatus = $VCWebCheck| Select-Object @{N="VC Web URL";E={$VCURL}},StatusCode,@{N="StatusDescription";E={"OK"}} |
ConvertTo-Html -Fragment -PreContent "<h2>vCenter Connection Response</h2>"
}
Else
{
$VCResponseStatus = $ErrorResponse | Select-Object @{N="VC Web URL";E={$_.ResponseUri}},StatusCode,
@{N="StatusDescription";E={$ErrorException.Message}} |
ConvertTo-Html -Fragment -PreContent "<h2>vCenter Connection Response</h2>"
}

## VMware Tools Version
Write-Host "Checking for out of date VMware tools" -ForegroundColor Green
$VMwareToolsReport = Get-VM | get-view | Select-Object Name,
@{N="HW Version";E={$_.Config.Version}}, @{N="ToolsVersion";E={$_.Config.tools.ToolsVersion}},
@{N="VMToolsStatus";E={$_.Guest.ToolsStatus}},@{N="ToolsVersionStatus";E={$_.Guest.ToolsVersionStatus}},@{N="VMPowerstatus";E={$_.runtime.PowerState}} |
Where-Object {$_.VMToolsStatus -Notlike "toolsOK" -and $_.VMPowerstatus -eq "poweredOn"}
if ($VMwareToolsReport) {
$vmToolsReport = $VMwareToolsReport | ConvertTo-HTML -Fragment -PreContent "<h2>VMwareTools Report</h2>"
}
else {
$vmToolsReport = "<h2>VMwareTools Report</h2>" + "No VMs With Out Of Date VMware Tools"
}

## Snapshots Older than three days
Write-Host "Checking for Snapshots older than $($snapshotdays) days" -ForegroundColor Green
$Snapshot = get-vm | get-snapshot
$SnapshotReport = $Snapshot | Select-Object vm, name,created,description | Where-Object {$_.created -lt $Snapshotdate}
if ($SnapshotReport) {
$SnapReport = $SnapshotReport | ConvertTo-HTML -Fragment -PreContent "<h2>Snapshot Report (More Than 10 Days Old)</h2>" }
else {
$SnapReport = "<h2>Snapshot Report</h2>" + "No Snapshots older than $($snapshotdays)"
}


## Total ESXi Hosts
Write-Host "Checking for ESXi Hosts Connected to this vCenter server" -ForegroundColor Green
$esxi = Get-VMHost
$esxiHostsReport = $esxi | Select Name,connectionState,PowerState,NumCpu,CpuUsageMhz,CpuTotalMhz,MemoryUsageGB,MemoryTotalGB,version, @{N="Cluster";E={Get-Cluster -VMHost $_ }}
if ($esxiHostsReport) {
$esxiReport = $esxiHostsReport | ConvertTo-HTML -Fragment -PreContent "<h2>Total ESXi Hosts Connected</h2>" }
#else {
#$SnapReport = "<h2>Snapshot Report</h2>" + "No Snapshots older than $($snapshotdays)"
#}


## ESXi-Cluster Details\Status
Write-Host "Checking for ESXi Cluster Details\Status on vCenter server $VCServer" -ForegroundColor Green
$cluster = Get-Cluster
$ClusterReport = $cluster | Select Name,HAEnabled,HAAdmissionControlEnabled,HAFailoverLevel,HARestartPriority,DrsEnabled,DrsMode,DrsAutomationLevel,EVCMode,HATotalSlots,HAUsedSlots,HAAvailableSlots,HASlotCpuMHz
if ($ClusterReport) {
$ClusterStatusReport = $ClusterReport | ConvertTo-HTML -Fragment -PreContent "<h2>ESXi-Cluster Details & Status</h2>" }


## VMHost Alarms
Write-Host "Checking for active VMware host alarms" -ForegroundColor Green
$VMHAlarmReport = @()
$VMHostStatus = (Get-VMHost | Get-View) | Select-Object Name,OverallStatus,ConfigStatus,TriggeredAlarmState
$HostErrors= $VMHostStatus | Where-Object {$_.OverallStatus -ne "Green" -and $_.TriggeredAlarmState -ne $null}
if ($HostErrors){
foreach ($hosterror in $HostErrors){
foreach($alarm in $HostError.TriggeredAlarmState){
$Hprops = @{
Host = $HostError.Name
OverAllStatus = $HostError.OverallStatus
TriggeredAlarms = (Get-AlarmDefinition -Id $alarm.alarm).Name
}
[array]$VMHAlarmReport += New-Object PSObject -Property $Hprops
}
}
}

if ($VMHAlarmReport){
$VMHAlarms = $VMHAlarmReport | Select-Object Host,OverAllStatus,TriggeredAlarms | ConvertTo-HTML -Fragment -PreContent "<h2>VMHost Alerts</h2>"
}
else{
$VMHAlarms = "<h2>VMHost Alerts</h2>" + "No active alarms for VMware hosts"
}

## VM Alarms
Write-Host "Checking for active VM alarms" -ForegroundColor Green
$VMAlarmReport = @()
$VMStatus = (Get-VM | Get-View) | Select-Object Name,OverallStatus,ConfigStatus,TriggeredAlarmState
$VMErrors = $VMStatus | Where-Object {$_.OverallStatus -ne "Green"}
if ($VMErrors) {
foreach ($VMError in $VMErrors){
foreach ($TriggeredAlarm in $VMError.TriggeredAlarmstate) {
$VMprops = @{
VM = $VMError.Name
OverAllStatus = $VMError.OverallStatus
TriggeredAlarms = (Get-AlarmDefinition -Id $TriggeredAlarm.Alarm).Name
}
[array]$VMAlarms += New-Object PSObject -Property $VMprops
}
}
}

if ($VMAlarms){
$VMAlarmReport = $VMAlarms | ConvertTo-HTML -Fragment -PreContent "<h2>VM Alerts</h2>"
}
else{
$VMAlarmReport = "<h2>VM Alerts</h2>" + "No active alarms for VM"
}

## Vcenter Events
Write-Host "Checking for Critical events for the last 12 hours" -ForegroundColor Green
$start = (Get-Date).AddHours(-12)
$VCAlerts = Get-VIEvent -Start $start -MaxSamples ([int]::MaxValue) |
Where-Object {$_ -is [VMware.Vim.AlarmStatusChangedEvent] -and ($_.To -match "red|yellow") -and
($_.FullFormattedMessage -notlike "*Virtual machine*")`
-and ($_.CreatedTime -gt $VCEventDate)}
if ($VCAlerts) {
$ActiveVCAlert = $VCAlerts | Select-Object @{N="vCenter Events";E={$_.FullFormattedMessage}},CreatedTime | Sort-Object -Property CreatedTime -Descending |
ConvertTo-Html -Fragment -PreContent "<h2>vCenter Alerts</h2>"
}
else
{
$ActiveVCAlert = "<h2>vCenter Alerts</h2>" + "No Active Alerts For The Last 12Hours"
}

## Datastore Functions
Write-Host "Checking for datastores below $($datastorePrecFree)% free space" -ForegroundColor Green
$DSReport = Get-Datastore | Select-Object Name,@{N="UsedSpaceGB";E={[math]::Round(($_.CapacityGB),2)}},
@{N="FreeSpaceGB";E={[math]::Round(($_.FreeSpaceGB),2)}},
@{N="%Free";E={[math]::Round(($_.FreeSpaceGB)/($_.CapacityGB)*100,2)}}
$DSBelow = $DSReport | Where-Object {$_."%Free" -lt $($datastorePrecFree)}
if ($DSBelow) {
$DSExport = $DSBelow | ConvertTo-HTML -Fragment -PreContent "<h2>DataStore Under $($datastorePrecFree)% Free Space</h2>"
}
else{
$DSExport = "<h2>DataStore Under $($datastorePrecFree)% Free Space</h2>" + "No DataStores below $($datastorePrecFree)% free space"
}

## check for old reports
$file = Get-ChildItem $ReportExport\$VCServer-DailyReport.Csv -ErrorAction SilentlyContinue
if (!$file){
Remove-Item $ReportExport\$VCServer-DailyReport.Csv -ErrorAction SilentlyContinue
}

## export results
ConvertTo-Html -Body "$Heading $VCConnect $VCResponseStatus $esxiReport $ClusterStatusReport $vmToolsReport $SnapReport $VMHAlarms $VMAlarmReport $ActiveVCAlert $DSExport" -Head $HTMLFormat |
Out-File $ReportExport\$VCServer-DailyReport_$date.htm

## Mail variables
#Send-MailMessage -From $FromAddress -To $toaddress -Subject $subject
#-Body "VMware Daily Report attached" -SmtpServer $SMTPServer -Attachments $ReportExport\$VCServer-DailyReport_$date.htm

## Report export location
Write-Host "Report has been exported to $ReportExport\$VCServer-DailyReport_$date.htm" -ForegroundColor Yellow
## Disconnect session from VC
disconnect-viserver -confirm:$false
}

Reply
0 Kudos
jsforth777
Contributor
Contributor
Jump to solution

Great script! It read where I changed the SSL certs over to CA as opposed to self-signed on some of the hosts and not all of them. The webpage comes up secure and shows my CA cert, but the script still pulled the self-signed information.

 

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

Did the changes come up with the correct certificates after some time?
It might be that the CertificateManager data is not refreshed immediately after such a change.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
ShoHRock
Enthusiast
Enthusiast
Jump to solution

@LucD the script above does not work, what am I doing wrong?

Error: Get-View : Cannot validate argument on parameter 'Id'. The argument is null or empty. Provide an argument that is not
null or empty, and then try the command again.
At G:\XXX\scripts\cert-esxi-x.ps1:15 char:27
+ ... gr = Get-View -Id $esx.ExtensionData.ConfigManager.CertificateManager
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Get-View], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutomation.ViCore.Cmdlets.Commands.DotNetInte
rop.GetVIView

=========================================

$ReportFileX = Get-Date -UFormat "G:\XXX\scripts\reports\certs-%Y-%b-%d @ %I-%M%p.html"

Connect-VIServer ABC

Get-VMHost -PipelineVariable esx |
ForEach-Object -Process {
$certMgr = Get-View -Id $esx.ExtensionData.ConfigManager.CertificateManager
New-Object -TypeName PSObject -Property ([ordered]@{
VMHost = $esx.Name
CertIssuer = $certMgr.CertificateInfo.Issuer
CertSubject = $certMgr.CertificateInfo.Subject
CertExpiration = $certMgr.CertificateInfo.NotAfter
CertStatus = $certMgr.CertificateInfo.Status
})
} | ConvertTo-Html  | out-file $ReportFileX

=========================================

Reply
0 Kudos
LucD
Leadership
Leadership
Jump to solution

It looks as if there is nothing in $esx when the Get-View is executed.

The error mentions line 15 while the Get-View in the script you shared is not on line 15.
Are there other lines in your script we can't see?


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

Reply
0 Kudos
Sudarshan_Bhart
Enthusiast
Enthusiast
Jump to solution

Works like a cake walk with vCenter 8 but nothing on vCenter 7. CertificateInfo is empty for all the Hosts.

Reply
0 Kudos