kirtyakshay
Contributor
Contributor

Script to run ntpd -p command on all hosts

Jump to solution

If I connect to a single ESXi host using SSH and run the command ntpq -p, I get the output as below :

pastedImage_1.png

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

Tags (2)
0 Kudos
1 Solution

Accepted Solutions
LucD
Leadership
Leadership

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.

$user = 'root'

$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

View solution in original post

0 Kudos
23 Replies
Nawals
Expert
Expert

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

NKS Please Mark Helpful/correct if my answer resolve your query.
0 Kudos
kirtyakshay
Contributor
Contributor

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

0 Kudos
Nawals
Expert
Expert

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.

NKS Please Mark Helpful/correct if my answer resolve your query.
0 Kudos
LucD
Leadership
Leadership

Export-Csv might be a bit easier :smileygrin:

And please, don't beg for points


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

0 Kudos
Nawals
Expert
Expert

Its not for point I see the query I help as I use this script long back. You are guru in PowerCLi. 🙂

NKS Please Mark Helpful/correct if my answer resolve your query.
0 Kudos
LucD
Leadership
Leadership

Thanks for removing that annoying footer Smiley Happy


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

0 Kudos
kirtyakshay
Contributor
Contributor

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 :

pastedImage_0.png

Did I miss anything ?

Thanks,

Akshay

0 Kudos
Nawals
Expert
Expert

Please try this Export-Csv 'D:\Akshay\YUL-V720-VMVC01.csv' --Encoding utf8 -NoTypeInformation

NKS Please Mark Helpful/correct if my answer resolve your query.
0 Kudos
kirtyakshay
Contributor
Contributor

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 :

pastedImage_0.png

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

0 Kudos
LucD
Leadership
Leadership

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.

$user = 'root'

$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

View solution in original post

0 Kudos
kirtyakshay
Contributor
Contributor

LucD​...This is what I get :

pastedImage_1.png

Thanks,

Akshay

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
kirtyakshay
Contributor
Contributor

Yes....please check, I have attached.

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
kirtyakshay
Contributor
Contributor

I am still getting the same :

pastedImage_0.png

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

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
kirtyakshay
Contributor
Contributor

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 :

pastedImage_0.png

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

0 Kudos
LucD
Leadership
Leadership

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

0 Kudos
kirtyakshay
Contributor
Contributor

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:

pastedImage_0.png

This however generates an output file but the last 4 columns are missing.

pastedImage_1.png

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

0 Kudos