If I connect to a single ESXi host using SSH and run the command ntpq -p, I get the output as below :
I know I can get the configured NTP server and the service running status using RV Tools however I am looking for a script to pull all the details seen in the above screenshot from all the ESXi hosts in a vCenter. I am not good in scripting and still learning it.
Can anyone please help me with a script so that I can connect to the vCenter and run that to get the output in a file for all the hosts ?
Any help would be really appreciable.
Thanks in advance!
Akshay Kirty
May I suggest using the Posh-SSH module (and forget about PuTTY).
See my Use Posh-SSH instead of PuTTY post.
The script would then look something like this.
Note that when there is no ntp configured on an ESXi node, the Reach, Delay, Offset and Jitter fields will be empty.
$pswd = 'VMware1!'
$cred = New-Object PSCredential -ArgumentList $user,(ConvertTo-SecureString -String $pswd -AsPlainText -Force)
Get-VMHost -PipelineVariable esx |
ForEach-Object -Process {
$sshService = Get-VMHostService -VMHost $_ | where{$_.Key -eq 'TSM-SSH'}
if(-not $sshService.Running){
Start-VMHostService -HostService $sshService -Confirm:$false | Out-Null
}
$session = New-SSHSession -ComputerName $_.Name -Credential $cred –AcceptKey
$result = Invoke-SSHCommand -SSHSession $session -Command 'ntpq -p'
Remove-SSHSession -SSHSession $session | Out-Null
$obj = [pscustomobject]@{
VMHost = $esx.Name
'NTP Service Running' = Get-VMHostService -VMHost $_ | where{$_.Key -eq 'ntpd'} | select -ExpandProperty Running
'NTP Server(s)' = (Get-View -Id $_.ExtensionData.ConfigManager.DatetimeSystem).DateTimeInfo.NtpConfig.Server -join '| '
}
if($result.Output[0].Length -eq 0){
Write-Host "No output from 'ntpq -p on $($esx.Name)'"
}
else{
$fields = (($result.Output | where{$_ -match '^\*'}) -replace '\s+',' ').Split(' ')
Add-Member -InputObject $obj -Name 'Reach' -Value $fields[6] -MemberType NoteProperty
Add-Member -InputObject $obj -Name 'Delay' -Value $fields[7] -MemberType NoteProperty
Add-Member -InputObject $obj -Name 'Offset' -Value $fields[8] -MemberType NoteProperty
Add-Member -InputObject $obj -Name 'Jitter' -Value $fields[9] -MemberType NoteProperty
}
$obj
if(-not $sshService.Running){
Stop-VMHostService -HostService $sshService -Confirm:$false | Out-Null
}
} |
Sort-Object -Property {$_.psObject.Properties.Name.Count} -Descending |
Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
This version of the script will start/stop the SSH service on each ESXi node, this to allow to run the ntpq command. you can manually connect vcenter instance and then run it.
$user = 'root'
$pswd = 'pswd'
$plink = 'C:\Putty\plink.exe'
$plinkoptionsPre = " -pw $Pswd"
$plinkoptions = " -batch -pw $Pswd"
$cmd1 = 'ntpq -p'
$remoteCommand = '"' + $cmd1 + '"'
$sMail = @{
From = 'me@domain.com'
To = 'me@domain.com'
SmtpServer = 'mail.domain.com'
Subject = 'NTP Report'
BodyAsHtml = $true
Body = Get-VMHost | Select Name,
@{N='NTP Service Running';E={Get-VMHostService -VMHost $_ | where{$_.Key -eq 'ntpd'} | select -ExpandProperty Running}},
@{N='NTP Server(s)';E={(Get-View -Id $_.ExtensionData.ConfigManager.DatetimeSystem).DateTimeInfo.NtpConfig.Server -join '| '}},
@{N='Reach';E={
$serviceSSH = Get-VMHostService -VMHost $_ | Where{$_.Label -eq 'SSH'}
if(!$serviceSSH.Running){
Start-VMHostService -HostService $serviceSSH -Confirm:$false > $null
}
$command = "echo Y | " + $plink + " " + $plinkoptionsPre + " " + $User + "@" + $_.Name + " " + """exit"""
$dummy = Invoke-Expression -Command $command
$command = $plink + " " + $plinkoptions + " " + $User + "@" + $_.Name + " " + $remoteCommand
$msg = Invoke-Expression -command $command
$script:fields = (($msg | where{$_ -match '^\*'}) -replace '\s+',' ').Split(' ')
if(!$serviceSSH.Running){
Stop-VMHostService -HostService $serviceSSH -Confirm:$false > $null
}
$script:fields[6]}},
@{N='Delay';E={$script:fields[7]}},
@{N='Offset';E={$script:fields[8]}},
@{N='Jitter';E={$script:fields[9]}} | ConvertTo-Html | Out-String
}
Send-MailMessage @SMail
Thank you so much for this.
I will try this now however was just wondering if it is possible to get this output in an excel or a .csv file instead of sending it as an HTML over mail.
Thanks,
Akshay
If you want to csv format then you can use ConvertTo-Csv -NoTypeInformation |out-file -FilePath dir-list.csv -Encoding utf8
Please mark correct or helpful if you get your answer.
Export-Csv might be a bit easier :smileygrin:
And please, don't beg for points
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Its not for point I see the query I help as I use this script long back. You are guru in PowerCLi. 🙂
Thanks for removing that annoying footer
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I did change the script the script a bit as below :
$user = 'root'
$pswd = 'XXXXX'
$plink = 'C:\Putty\plink.exe'
$plinkoptionsPre = " -pw $Pswd"
$plinkoptions = " -batch -pw $Pswd"
$cmd1 = 'ntpq -p'
$remoteCommand = '"' + $cmd1 + '"'
$ESXihost = Get-VMHost | Select Name,
@{N='NTP Service Running';E={Get-VMHostService -VMHost $_ | where{$_.Key -eq 'ntpd'} | select -ExpandProperty Running}},
@{N='NTP Server(s)';E={(Get-View -Id $_.ExtensionData.ConfigManager.DatetimeSystem).DateTimeInfo.NtpConfig.Server -join '| '}},
@{N='Reach';E={
$serviceSSH = Get-VMHostService -VMHost $_ | Where{$_.Label -eq 'SSH'}
if(!$serviceSSH.Running){
Start-VMHostService -HostService $serviceSSH -Confirm:$false > $null
}
$command = "echo Y | " + $plink + " " + $plinkoptionsPre + " " + $User + "@" + $_.Name + " " + """exit"""
$dummy = Invoke-Expression -Command $command
$command = $plink + " " + $plinkoptions + " " + $User + "@" + $_.Name + " " + $remoteCommand
$msg = Invoke-Expression -command $command
$script:fields = (($msg | where{$_ -match '^\*'}) -replace '\s+',' ').Split(' ')
if(!$serviceSSH.Running){
Stop-VMHostService -HostService $serviceSSH -Confirm:$false > $null
}
$script:fields[6]}},
@{N='Delay';E={$script:fields[7]}},
@{N='Offset';E={$script:fields[8]}},
@{N='Jitter';E={$script:fields[9]}} | Export-Csv 'D:\Akshay\YUL-V720-VMVC01.csv' -NoTypeInformation
However the output does not have the last four column information :
Did I miss anything ?
Thanks,
Akshay
Please try this Export-Csv 'D:\Akshay\YUL-V720-VMVC01.csv' --Encoding utf8 -NoTypeInformation
Not sure what am I missing. I tried with Export-Csv 'D:\Akshay\YUL-V720-VMVC01.csv' --Encoding utf8 -NoTypeInformation but I get the below :
Also tried the below from : PowerCLI script to monitor NTP and e-mail report
$user = 'root'
$pswd = 'XXXXXX'
$plink = 'C:\Putty\plink.exe'
$plinkoptions = " -batch -pw $Pswd"
$cmd1 = 'ntpq -p'
$remoteCommand = '"' + $cmd1 + '"'
$ESXihost = Get-VMHost | Select Name,
@{N='NTP Service Running';E={Get-VMHostService -VMHost $_ | where{$_.Key -eq 'ntpd'} | select -ExpandProperty Running}},
@{N='NTP Server(s)';E={(Get-View -Id $_.ExtensionData.ConfigManager.DatetimeSystem).DateTimeInfo.NtpConfig.Server -join '| '}},
@{N='Reach';E={
$command = $plink + " " + $plinkoptions + " " + $User + "@" + $_.Name + " " + $remoteCommand
$msg = Invoke-Expression -command $command
$script:fields = (($msg | where{$_ -match '^\*'}) -replace '\s+',' ').Split(' ')
$script:fields[6]}},
@{N='Delay';E={$script:fields[7]}},
@{N='Offset';E={$script:fields[8]}},
@{N='Jitter';E={$script:fields[9]}} | Export-Csv 'D:\Akshay\YUL-V720-VMVC01.csv' -NoTypeInformation
This one also generates the report, but still the last 4 columns are blank.
Thanks,
Akshay
May I suggest using the Posh-SSH module (and forget about PuTTY).
See my Use Posh-SSH instead of PuTTY post.
The script would then look something like this.
Note that when there is no ntp configured on an ESXi node, the Reach, Delay, Offset and Jitter fields will be empty.
$pswd = 'VMware1!'
$cred = New-Object PSCredential -ArgumentList $user,(ConvertTo-SecureString -String $pswd -AsPlainText -Force)
Get-VMHost -PipelineVariable esx |
ForEach-Object -Process {
$sshService = Get-VMHostService -VMHost $_ | where{$_.Key -eq 'TSM-SSH'}
if(-not $sshService.Running){
Start-VMHostService -HostService $sshService -Confirm:$false | Out-Null
}
$session = New-SSHSession -ComputerName $_.Name -Credential $cred –AcceptKey
$result = Invoke-SSHCommand -SSHSession $session -Command 'ntpq -p'
Remove-SSHSession -SSHSession $session | Out-Null
$obj = [pscustomobject]@{
VMHost = $esx.Name
'NTP Service Running' = Get-VMHostService -VMHost $_ | where{$_.Key -eq 'ntpd'} | select -ExpandProperty Running
'NTP Server(s)' = (Get-View -Id $_.ExtensionData.ConfigManager.DatetimeSystem).DateTimeInfo.NtpConfig.Server -join '| '
}
if($result.Output[0].Length -eq 0){
Write-Host "No output from 'ntpq -p on $($esx.Name)'"
}
else{
$fields = (($result.Output | where{$_ -match '^\*'}) -replace '\s+',' ').Split(' ')
Add-Member -InputObject $obj -Name 'Reach' -Value $fields[6] -MemberType NoteProperty
Add-Member -InputObject $obj -Name 'Delay' -Value $fields[7] -MemberType NoteProperty
Add-Member -InputObject $obj -Name 'Offset' -Value $fields[8] -MemberType NoteProperty
Add-Member -InputObject $obj -Name 'Jitter' -Value $fields[9] -MemberType NoteProperty
}
$obj
if(-not $sshService.Running){
Stop-VMHostService -HostService $sshService -Confirm:$false | Out-Null
}
} |
Sort-Object -Property {$_.psObject.Properties.Name.Count} -Descending |
Export-Csv -Path .\report.csv -NoTypeInformation -UseCulture
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
LucD...This is what I get :
Thanks,
Akshay
Can you attach (bottom right in the edit window) the script as you are running it (anonymise the critical data)?
It looks as if your copy/paste might have some issues.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
The attached script works perfectly for me.
Not sure why, but the line number (line 40 ?) in the error message doesn't correspond with the attached script.
Did you add code that is not in the attached script?
Also, I noticed that the quote was supposed to be earlier.
Change that line to
Write-Host "No output from 'ntpq -p' on $($esx.Name)"
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I am still getting the same :
Just to make sure I am not making any mistakes while copy pasting, can i please request you to attached the .ps1 file that you are using ?
Thanks,
Akshay
That error on line 40 seems to indicate that you have other code added.
That would make it difficult to analyse the issue only based on part of the code.
The script, as you attached it works fine.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
I noticed a strange thing.
When I try to open the script in Notepad++, everything looks good but when I open it in PowerShell, I notice this strange character :
I tried to manually replace this with what is there in your script, but the result is still the same error.
Something similar to what is mentioned here : https://www.reddit.com/r/PowerShell/comments/6tgo82/getting_error_the_string_is_missing_the_terminat...
Could this be the reason ?
Thanks,
Akshay
That is probably an explanation.
I attached the script as an UTF-8 file, try that one.
Blog: lucd.info Twitter: @LucD22 Co-author PowerCLI Reference
Hi LucD
I really appreciate you taking time to look into this issue however when I opened the script, I found the same character as in the screenshot that I shared earlier.
I then manually changed it as below and executed the script but now I am getting new errors:
This however generates an output file but the last 4 columns are missing.
The machine that I am running the script from is a new Windows Server 2016 Jump box and I have just installed the PowerCli on it.
Do i need to install or import any module ?
Thanks,
Akshay