##########################################################################################
# esx-time.ps1
#
# Gather local time and time zone for all servers in AD.
# Report servers with time different from machine on which script is run
# E-Mail report to designated recipient.
#
# Requires vmware power cli
# "set-powercliconfiguration -InvalidCertificateAction Ignore" to ignore cert errors
#
#
##########################################################################################
Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
#VCS
$vcs="privcs01" # PRIVDIVC1, PRIDEVVC1, PRIVCSVDI01, SECVCS01
# E-Mail Recipient
$recipient="administrator@DOMAIN.com"
# Greatest acceptable time difference
$maxdiff=59
$outfile = "c:\dev\esx-time.html"
$user = "usa\svc_vmware"
$pw = Read-Host "Password for $user" -AsSecureString
$rootpw = Read-Host "Password for root" -AsSecureString
#convert $pw to plain text
$pass = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($pw))
#convert $rootpw to plain text
$rootpass = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($rootpw))
############################################################################################
# Get List of Host Names from VCS server
#
write-host "Getting Server List from VCS"
connect-viserver -Server $vcs -User $user -Password $pass -ErrorAction SilentlyContinue > $null
$hosts = get-vmhost
disconnect-viserver -confirm:$false -ErrorAction SilentlyContinue > $null
$list = @()
foreach ($Server in $hosts) {
$Server = $Server -replace "\s{2,}", ""
$Server = $Server -replace "\.usa\.DOMAIN\.com", ""
if ($Server) { $list = $list + $Server } #skip a null value
}
$list = $list | sort-object
write-host "COMPLETE"
###
#clear-host
$today = get-date
############################################################################################
# Report Heading
$report=@'
VMWare Host Time Issues
'@
$report+=$today
$report+="
Server Date Time Off(s) "
############################################################################################
# Query every server in list
write-host "Checking each server:"
foreach ($item in $list) {
$flag=" "
$dt=""
$srvtime=""
$hour = ""
$min = ""
$sec = ""
$month = ""
$day = ""
$year = ""
$comp = ""
$d = ""
$t = ""
$computer = $item
$comp = "{0,-16}" -f $computer
$comp = $comp.padright(16," ")
write-host ">$computer<"
If (Test-Connection -computername $computer -Quiet -count 1){ #respond to ping?
write-host " PING - SUCCESS"
write-host " Time Query"
$output=""
$block = @'
$machine = $args[0]
$pass = $args[1]
Add-PSSnapin VMware.VimAutomation.Core -ErrorAction SilentlyContinue
connect-viserver -server $machine -user "root" -password $pass -WarningAction SilentlyContinue -ErrorAction SilentlyContinue > $null
# $time = (get-view serviceinstance).CurrentTime()
# $time
((get-view serviceinstance).CurrentTime())
'@
$sb = [scriptblock]::create($block)
$args=@()
$args = ($computer, $rootpass)
start-job -name $computer -scriptblock $sb -argumentlist $args > $null
Wait-Job -name $computer -Timeout 60 > $null
$output = Receive-Job $computer
#$output
#disconnect-viserver -server $computer -confirm:$false #-ErrorAction SilentlyContinue > $null
if ($output) {
$dt = $output
write-host "DT=$dt"
}
else {
write-host "$computer`tERROR: No time Query Output"
$report+='' + $comp + ' '
$report+='' + "ERROR - No response to date/time query" + ' '
$report+=' '
continue
} # end if output
}#end if ping
else { # No PING response
write-host "$computer`tERROR: No PING Response"
$report+='' + $comp + ' '
$report+='' + "CONNECTION ERROR: No response to PING" + ' '
$report+=' '
continue
}
[string] $month = [System.Convert]::ToString($dt.Month)
$month = $month.padleft(2,"0")
[string] $day = [System.Convert]::ToString($dt.Day)
$day = $day.padleft(2,"0")
[string] $year = [System.Convert]::ToString($dt.Year)
$year = $year.padleft(4,"0")
$d = $month + "/" + $day + "/" + $year
write-host " Date=$d"
[string] $hour = [System.Convert]::ToString($dt.Hour)
$hour = $hour.padleft(2,"0")
[string] $min = [System.Convert]::ToString($dt.Minute)
$min = $min.padleft(2,"0")
[string] $sec = [System.Convert]::ToString($dt.Second)
$sec = $sec.padleft(2,"0")
$t = $hour + ":" + $min + ":" + $sec
write-host " Time=$t"
if ($dt) { #$dt not null
$srvtime=($dt.Minute)*60+($dt.Second)
$refmin = ""
$refsec = ""
$now = get-date
$cmptime = ($now.Minute)*60+($now.Second)
[string] $min = [System.Convert]::ToString($now.Minute)
$refmin = $min.padleft(2,"0")
[string] $sec = [System.Convert]::ToString($now.Second)
$refsec = $sec.padleft(2,"0")
$reftime=$refmin+":"+$refsec
#Compare server time to script machine time.
$diff=$cmptime-$srvtime
write-host " Time Diff=$diff"
if (($diff -gt $maxdiff) -or ($diff -lt (-1*$maxdiff))) { $flag="*" }
write-host "$flag$comp`t$d`t$t`t$flag$diff$flag`t" $timezone.Description
if ($flag -eq "*") { #time difference is too great
$report+=('' + $comp + ' ')
$report+=('' + $d + ' ')
$report+=('' + $t + ' ')
$report+=('' + $diff + ' ')
$report+=(' ')
}
}# end if null
}#end foreach computer
###
$report+="
"
$report | out-file $outfile
############################################################################################
#e-mail the report
$messageSubject = "VMWare Host Time Report"
$smtpServer = "smtp.DOMAIN.com"
$smtpFrom = "noreply@DOMAIN.com"
$smtpTo = $recipient
$message = $report
send-mailmessage -to $smtpTo -from $smtpFrom -subject $messageSubject -body $message -smtpserver $smtpServer -BodyAsHtml
###
remove-job * -force
1/15/2014
Check Time on VMWare Hosts
Check Time on VMware Hosts
Similar to my previous script reporting on Windows Server time.
1/03/2014
Powershell Format Operator
Powershell Format Operator "-f"
| Operator | Example | Results | Description |
|---|---|---|---|
| {0} | Display a particular element | "{0} {1}" -f "a", "b" | a b |
| {0:x} | Display a number in Hexadecimal | "0x{0:x}" -f 181342 | 0x2c45e |
| {0:X} | Display a number in Hexadecimal uppercase | "0x{0:X}" -f 181342 | 0x2C45E |
| {0:dn} | Display a decimal number left justified, padded with zeros | "{0:d8}" -f 3 | 00000003 |
| {0:p} | Display a number as a percentage | "{0:p}" -f .123 | 12.30 % |
| {0:c} | Display a number as currency | "{0:c}" -f 12.34 | $12.34 |
| {0,n} | Display with field width n, left aligned | "|{0,5}|" -f "hi" | | hi| |
| {0,-n} | Display with field width n, right aligned | "|{0,-5}| -f "hi" | |hi | |
| {0:hh} {0:mm} | Display the hours and minutes from a date time value | "{0:hh}:{0:mm}" -f (Get-Date) | 01:34 |
| {0:C} | Display using the currency symbol for the current culture | "|{0,10:C}|" -f 12.3 | | $12.40| |
1/02/2014
Powershell: WMI Timeouts locking up scripts
There are a few folks with suggestions out there. One is to use a job to run the query. Unfortunately this leaves those jobs stuck out there so if a lot of my servers have WMI screwed up I suppose doing this could crash my management machine.
This example is to get the current time and time zone from every server machine in my AD domain.
"
$report | out-file $outfile
############################################################################################
#e-mail the report
$messageSubject = "Server Time Report"
$smtpServer = "smtp.domain.com"
$smtpFrom = "noreply@domain.com"
$smtpTo = $recipient
$message = $report
send-mailmessage -to $smtpTo -cc "admin@domain.com" -from $smtpFrom -subject $messageSubject -body $message -smtpserver $smtpServer -BodyAsHtml
###
remove-job * -force
There are a few folks with suggestions out there. One is to use a job to run the query. Unfortunately this leaves those jobs stuck out there so if a lot of my servers have WMI screwed up I suppose doing this could crash my management machine.
This example is to get the current time and time zone from every server machine in my AD domain.
########################################################################################## # CHECK-TIME.PS1 # # Gather local time and time zone for all servers in AD. Convert times to GMT & compare # Report servers with time different from machine on which script is run # E-Mail report to designated recipient. # ########################################################################################## # E-Mail Recipient $recipient="user@domain.com" # Greatest acceptable time difference $maxdiff=59 $outfile = "c:\dev\check-time.html" If (Test-Path $outfile){ Remove-Item $outfile } $logfile = "c:\dev\check-time.log" If (Test-Path $logfile){ Remove-Item $logfile } $mytimezone = get-wmiobject Win32_Computersystem -property CurrentTimeZone, daylightineffect $myoffset = $mytimezone.CurrentTimeZone #GMT offset in minutes $mydst = $mytimezone.daylightineffect if ($mydst) { $myoffset+=60 } ########################################################################################## # FUNCTION: Check for TCP response on $port function Test-Port { Param( [string] $srv, $port=135, $timeout=1500, [switch]$verbose ) # TCP connect $port $ErrorActionPreference = "SilentlyContinue" $tcpclient = new-Object system.Net.Sockets.TcpClient $iar = $tcpclient.BeginConnect($srv,$port,$null,$null) $wait = $iar.AsyncWaitHandle.WaitOne($timeout,$false) # Check to see if the connection is done if(!$wait) { # Close connection, report timeout $tcpclient.Close() if($verbose){write-host "Connection Timeout" } Return $false } else { # Close connection, report any error $error.Clear() $tcpclient.EndConnect($iar) | out-Null if(!$?){if($verbose){write-host $error[0]};$failed = $true} $tcpclient.Close() } # Return $true if connection established if($failed){ return $false } else { return $true } } # http://technet.microsoft.com/en-us/library/ff730959.aspx # # End of functions ########################################################################################## ############################################################################################ # Create $list of server names for all Windows servers in Active Directory # $strCategory = "computer" $strOS = "Windows*Server*" $objDomain = New-Object System.DirectoryServices.DirectoryEntry $objSearcher = New-Object System.DirectoryServices.DirectorySearcher $objSearcher.SearchRoot = $objDomain $objSearcher.Filter = ("OperatingSystem=$strOS") $colProplist = "dnshostname" foreach ($i in $colPropList){$objSearcher.PropertiesToLoad.Add($i)} $colResults = $objSearcher.FindAll() foreach ($objResult in $colResults) { $objComputer = $objResult.Properties; $Server = $objComputer.dnshostname $Server = $Server -replace "\s{2,}", "" $Server = $Server -replace "\.usa\.domain\.com", "" if ($Server) { $list = $list + $Server } #skip a null value } $list = $list | sort-object ### clear-host $today = get-date ############################################################################################ # Report Heading $report=@' Server Time Issues
'@ $report+=$today $report+="
| Server | Date | Time | Off(s) | Time Zone | " ############################################################################################ # Query every server in list foreach ($result in $list) { $flag=" " $timezone="" $dt="" $srvtime="" $hour = "" $min = "" $sec = "" $comp = "" $d = "" $t = "" $computer = $result $comp = "{0,-16}" -f $computer $comp = $comp.padright(16," ") #write-host ("$Computer"+":") #("$Computer"+":")|out-file $logfile -append If (Test-Connection -computername $computer -Quiet -count 1){ #respond to ping? $a = Test-Port $computer $dst="" $timezone="" $output="" $offset="" if ($a) { # resonds on RPC? #timezone $block = "get-wmiobject Win32_Computersystem -computer $computer -property CurrentTimeZone, daylightineffect" $sb = [scriptblock]::create($block) start-job -name $computer $sb > $null Wait-Job -name $computer -Timeout 10 > $null $output = Receive-Job $computer $block = "Get-WmiObject -class Win32_TimeZone -ComputerName $computer" $sb = [scriptblock]::create($block) start-job -name $computer $sb > $null Wait-Job -name $computer -Timeout 10 > $null $timezonedesc = Receive-Job $computer $tz = $timezonedesc.description if ($output -ne $null) { $timezone = $output $offset = $timezone.CurrentTimeZone #GMT offset in minutes $dst = $timezone.daylightineffect if ($dst) { $offset+=60 } } else { write-host "$computer`tERROR: No WMI Query Output" "$computer`tERROR: No WMI Query Output" | out-file $logfile -append $report+='
|---|---|---|---|---|
| ' + $comp + ' | ' $report+='' + "WMI ERROR - No response to timezone query" + ' | ' $report+='|||
| ' + $comp + ' | ' $report+='' + "WMI ERROR - No response to date/time query" + ' | ' $report+='|||
| ' + $comp + ' | ' $report+='' + "RPC ERROR - No response on port " + $port + ' | ' $report+='|||
| ' + $comp + ' | ' $report+='' + "CONNECTION ERROR: No response to PING" + ' | ' $report+='|||
| ' + $comp + ' | ') $report+=('' + $d + ' | ') $report+=('' + $t + ' | ') $report+=('' + $diff + ' | ') $report+=('' + $zone + ' | ') $report+=('
Dealing with WMI Timeouts — Steven Murawski
Dealing with WMI Timeouts — Steven Murawski: Dealing with WMI Timeouts
Get-WmiCustom (aka: Get-WMIObject with timeout!) - musc@> $daniele.work.ToString() - Site Home - MSDN Blogs
Get-WmiCustom (aka: Get-WMIObject with timeout!) - musc@> $daniele.work.ToString() - Site Home - MSDN Blogs: Unfortunately, the Get-WmiObject cmdlet does not let you specify a timeout. Therefore I cooked my own function which has a compatible behaviour to that of Get-WmiObject, but with an added “-timeout” parameter which can be set.
Function Get-WmiCustom([string]$computername,[string]$namespace,[string]$class,[int]$timeout=15)
{
$ConnectionOptions = new-object System.Management.ConnectionOptions
$EnumerationOptions = new-object System.Management.EnumerationOptions
$timeoutseconds = new-timespan -seconds $timeout
$EnumerationOptions.set_timeout($timeoutseconds)
$assembledpath = "\\" + $computername + "\" + $namespace
#write-host $assembledpath -foregroundcolor yellow
$Scope = new-object System.Management.ManagementScope $assembledpath, $ConnectionOptions
$Scope.Connect()
$querystring = "SELECT * FROM " + $class
#write-host $querystring
$query = new-object System.Management.ObjectQuery $querystring
$searcher = new-object System.Management.ManagementObjectSearcher
$searcher.set_options($EnumerationOptions)
$searcher.Query = $querystring
$searcher.Scope = $Scope
trap { $_ } $result = $searcher.get()
return $result
}
Subscribe to:
Posts (Atom)