Tuesday, September 1, 2015

Time variance across a domain.

In my never ending quest to rid myself of time sync issues I created the following PowerShell script.  I wrote it some time ago and can't recall if I borrowed bits so if you see what looks like your code snippets in there forgive me.

The script scans the current domain using the current users credentials.  It generates an Excel spreadsheet and populates it with the names of all Windows systems it finds.  I have an exclusion to bypass anything with ESX in the name so my VMware hosts are ignored.  It then does a time comparison between the PDC and the target PC and logs the results to the spreadsheet.

<#==============================================================================
         File Name : Domain-Time-Validator.ps1
   Original Author : Kenneth C. Mazie (kcmjr AT kcmjr DOT com)
                   :
       Description : Scans a domain and reports the time variance between the PDC and the target
                   :
             Notes : Normal operation is with no command line options.  Spreadsheet
                   : is written to C:\Scripts.  Console display counts down to zero
                   : so you know where it's at.
                   :
        Arguements : -console $true (defaults to false) use this to display to local console.
                   :
                   :
          Warnings : None
                   :  
             Legal : Public Domain. Modify and redistribute freely. No rights reserved.
                   : SCRIPT PROVIDED "AS IS" WITHOUT WARRANTIES OR GUARANTEES OF
                   : ANY KIND. USE AT YOUR OWN RISK. NO TECHNICAL SUPPORT PROVIDED.
                   :
           Credits : Code snippets and/or ideas came from many sources including but
                   : not limited to the following:
                   :
    Last Update by : Kenneth C. Mazie
   Version History : v1.0 - 06-10-14 - Original
    Change History : v1.1 - 00-00-00 - Tweaked inline documentation
                   :
#=============================================================================#>
#requires -version 3.0

Param(
     [bool]$Console = $False
     )
If ($Console){$Script:Console = $true}   #--[ Just to be sure... ]--
Clear-Host

#--[ Excel Non-Interactive Fix ]------------------------------------------------
If (!(Test-path -Path "C:\Windows\System32\config\systemprofile\Desktop")){New-Item -Type Directory -Name "C:\Windows\System32\config\systemprofile\Desktop"}
If (!(Test-path -Path "C:\Windows\SysWOW64\config\systemprofile\Desktop")){New-Item -Type Directory -Name "C:\Windows\SysWOW64\config\systemprofile\Desktop"}
#--[ Excel will crash when run non-interactively via a scheduled task if these folders don't exist ]--

$Datafile = "C:\Scripts\TimeSyncData.xlsx"
$Row = 0
$Col = 1
#--[ Create new Excel object ]--------------------------------------------------
$Excel = New-Object -Com Excel.Application
$Excel.visible = $true
$Excel.DisplayAlerts = $false
$Excel.ScreenUpdating = $true
$Excel.UserControl = $true
$Excel.Interactive = $true
$Workbook = $Excel.Workbooks.Add()
$WorkSheet = $Workbook.WorkSheets.Item(1)
# Write Worksheet title
#$WorkSheet.Cells.Item(1,1) = "Local Administrator Group Membership Report - $DateTime"
#$WorkSheet.Cells.Item(1,1).font.bold = $true
#$WorkSheet.Cells.Item(1,1).font.underline = $true
#$WorkSheet.Cells.Item(1,1).font.size = 18
# Write worksheet column headers
$Row ++
$WorkSheet.Cells.Item($Row,$Col) = "TARGET:"
$WorkSheet.Cells.Item($Row,$Col).font.bold = $true
$WorkSheet.Cells.Item($Row,$Col).HorizontalAlignment = 1
#$WorkSheet.Cells.Item($Row,$Col).Borders.Item(10).LineStyle = 1
#$WorkSheet.Cells.Item($Row,$Col).Borders.Item(10).Weight = 4
$Col++
$WorkSheet.Cells.Item($Row,$Col) = "PDC Time:"
$WorkSheet.Cells.Item($Row,$Col).font.bold = $true
$WorkSheet.Cells.Item($Row,$Col).HorizontalAlignment = 1
#$WorkSheet.Cells.Item($Row,$Col).Borders.Item(10).LineStyle = 1
#$WorkSheet.Cells.Item($Row,$Col).Borders.Item(10).Weight = 4
$Col++
$WorkSheet.Cells.Item($Row,$Col) = "Target Time:"
$WorkSheet.Cells.Item($Row,$Col).font.bold = $true
$WorkSheet.Cells.Item($Row,$Col).HorizontalAlignment = 1
#$WorkSheet.Cells.Item($Row,$Col).Borders.Item(10).LineStyle = 1
#$WorkSheet.Cells.Item($Row,$Col).Borders.Item(10).Weight = 4
$Col++
$WorkSheet.Cells.Item($Row,$Col) = "Variance:"
$WorkSheet.Cells.Item($Row,$Col).font.bold = $true
$WorkSheet.Cells.Item($Row,$Col).HorizontalAlignment = 1
#$WorkSheet.Cells.Item($Row,$Col).Borders.Item(10).LineStyle = 1
#$WorkSheet.Cells.Item($Row,$Col).Borders.Item(10).Weight = 4
$Resize = $WorkSheet.UsedRange
[void]$Resize.EntireColumn.AutoFit()
$Row++
$Col = 1

#--[ Identify the PDC ]---------------------------------------------------------
$Script:PDC = (Get-ADDomain).pdcemulator
$Script:Source = $Script:PDC.split(".")[0]

#--[ Get the list of targets ]--------------------------------------------------
$Computers = Get-ADComputer -Filter {operatingsystem -like "*windows*" -and name -notlike "*esx*"} | sort name
$Total = $Computers.Count

#--[ Cycle through targets ]----------------------------------------------------
ForEach($Script:Target in $Computers ){
       $Script:Target = $Script:Target.name
      
       $Col = 1
#      $WorkSheet.Cells.Item(1,1).font.colorindex = 1
       $WorkSheet.Cells.Item($row,$col) = $Script:Target
       $Col++
       If ($Script:Console){Write-Host "--[ $Script:Target ]--[ $Total ]--------------------------------------------" -ForegroundColor Cyan }
       If(Test-Connection -ComputerName $Script:Target -count 1 -BufferSize 16 -ErrorAction SilentlyContinue ) {
              $Script:SourceDate = invoke-command -ComputerName $Script:Source -ScriptBlock {get-date}
              $Script:TargetDate = invoke-command -ComputerName $Script:Target -ScriptBlock {get-date}
              $Script:TimeSpan = [DateTime]$Script:SourceDate - [DateTime]$Script:TargetDate
             
              If($Script:TimeSpan.seconds -lt 0){$Script:Offset = "Plus"}Else{$Script:Offset = "Minus"}
             
              $Script:Inspect = new-timespan -Start (icm $Source {get-date}) -end (icm $Script:Target {get-date})
      
              If ($Script:Console){Write-Host "PDC Time    :" $Script:SourceDate}
              $WorkSheet.Cells.Item($row,$col) = $Script:SourceDate
              $Col++
              If ($Script:Console){Write-Host "Target Time :" $Script:TargetDate}
              $WorkSheet.Cells.Item($row,$col) = $Script:TargetDate
              $Col++
              If ($Script:Console){Write-Host "Variance    : " -NoNewline }
              If($Script:TimeSpan.minutes -ge 5 -or $Script:TimeSpan.minutes -lt -5){
                     $Color = "red"
                     $WorkSheet.Cells.Item($Row,$Col).font.colorindex = 9
              }Else{
                     $Color = "green"
                     $WorkSheet.Cells.Item($Row,$Col).font.colorindex = 10
              }

              $WorkSheet.Cells.Item($row,$col) = $Script:TimeSpan.Hours.tostring()+" Hours "+$Script:TimeSpan.Minutes.tostring()+" Min "+$Script:TimeSpan.seconds.tostring()+" Sec"
              If ($Script:Console){Write-Host $Script:TimeSpan.Hours.tostring() "Hours" $Script:TimeSpan.minutes.tostring() "Min" $Script:TimeSpan.seconds.tostring() "Sec" -ForegroundColor $Color }
       }Else{
              $WorkSheet.Cells.Item($Row,$Col).font.colorindex = 9
              $WorkSheet.Cells.Item($Row,$Col) = "Unable to connect to target..."
              If ($Script:Console){Write-Host "Unable to connect to target..." -ForegroundColor Red }
       }
       $Total --
       $Row++
       $Resize = $WorkSheet.UsedRange
       [void]$Resize.EntireColumn.AutoFit()
}


If ($Script:Console){Write-Host "--- Completed ---" -ForegroundColor Red  }

No comments:

Post a Comment