# Copyright © 2012, Microsoft Corporation. All rights reserved. Import-LocalizedData -BindingVariable localizationString -FileName CL_LocalizationData . ./utils_SetupEnv.ps1 . ./utils_reporting.ps1 . ./cl_mutexverifiers.ps1 . ./cl_windowsversion.ps1 . ./Cl_Service.ps1 #*================================================================================= #Function Check-SelfHelp #Purpose check if the this Script is running from MSDT #Return #*================================================================================= function Check-SelfHelp { param( [int]$ProcessID = $PID, [int]$Threshold = 30) [bool]$SelfHelp = $false $SHDiagProc = Get-Process -Id $ProcessID [datetime]$SHDiagStart = $SHDiagProc.Get_StartTime() [datetime]$min = $SHDiagStart.AddSeconds(-$Threshold) [datetime]$max = $SHDiagStart.AddSeconds($Threshold) $arrprocs = Get-Process |?{$_.Name -eq "msdt"} | Where-Object{ $_.Get_StartTime() -gt $min -and $_.Get_StartTime() -lt $max} $MSDTprocs = @() $arrprocs | ForEach-Object{$myID = $_.id; $MSDTprocs += Get-WmiObject Win32_Process | Where-Object {$_.ProcessID -eq $myID -and $_.CommandLine -ne $null} } if($MSDTprocs) { $MSDTprocs | ForEach-Object { if ($_.CommandLine -ilike "*/path*" -or $_.CommandLine -ilike "*/cab*"){$SelfHelp = $true}} } return $SelfHelp } #*================================================================================= #last week starting from midnight #*================================================================================= function Get-DateLastWeek(){ $lastweek = (get-date) - (new-timespan -day 8) $lastweek = $lastweek.addminutes(-($lastweek.minute)) $lastweek = $lastweek.addhours(-($lastweek.hour)) $lastweek = $lastweek.addseconds(-($lastweek.second)) return $lastweek } # Commenting Since Function not applicable to Windows 10 #*================================================================================= # returns the messages with warning and fatal as keywords in "windowsupdate.log" #*================================================================================= <#function Get-WarningAndFatalWindowsUpdateLog($pathWindowsUpdatelog){ # return messages with "WARNING:" or "FATAL:" # parameter for $pathWindowsUpdatelog should be ($env:windir+"\windowsupdate.log") if(!(test-path ($pathWindowsUpdatelog))){ return $null } $warningAndFatal = get-content $pathWindowsUpdatelog if($warningAndFatal -eq $null) { return $null } $warningAndFatalArray = @() foreach($w in $warningAndFatal) { if( ($w.indexof("WARNING:") -gt -1) -or ($w.indexof("FATAL:") -gt -1) ) { $warningAndFatalArray += $w } } return $warningAndFatalArray }#> # returns component and error code #*================================================================================= #Get-ComponentAndErrorCode #*================================================================================= function Get-ComponentAndErrorCode([string]$msg){ #[char]$tab=[char]9 #$var1=$msg.split($tab) #$codes=[regex]::matches($var1[5], "0x[a-f0-9a-f0-9A-F0-9A-F0-9]{6,8}") | % {$_.value} $codes=[regex]::matches($msg, "0x[a-f0-9a-f0-9A-F0-9A-F0-9]{6,8}") if($codes.count -gt 1){ $c1="" # there can be more than one error code can be returned for the same component at once foreach($c in $codes){ $c1+="_"+$c } return $c1 }else{ return $codes.Value } } # Commenting Since Function not called in any part of code - 21/04/15 # gets the dated log from given date to present date #*================================================================================= #Get-DatedLog #*================================================================================= <#function Get-DatedLog([datetime]$fromDate,$log){ $datedLog = @() if( ((isarray $log) -eq $false) ){ if( $fromDate -lt ($log.substring(0,10)) ){ return $log }else{ return $null } } if($log -eq $null) { return $null } for($i=0;$i -lt $log.Count ; $i=$i+1){ if($log[$i].trim() -eq ""){ continue } if( $fromDate -lt ($log[$i].substring(0,10)) ){ $datedLog += $log[$i] } } return $datedlog }#> # gets the dated events from given date to present date #*================================================================================= #Get-DatedEvents #*================================================================================= function Get-DatedEvents($eventlog){ $datedEvents = @() if($eventlog -eq $null) { return $null } foreach($evt in $eventlog) { $eventMsg = $evt.Message $datedEvents += $eventMsg } return $datedEvents } #Commenting Since Function not called in any part of code - 21/04/15 # returns the lines with error codes on it with warning and fatal keyword #*================================================================================= #Get-LatestWindowsUpdateErrorFromLog #*================================================================================= <#function Get-LatestWindowsUpdateErrorFromLog($log){ if($log -eq $null) { return $null } $codes="0x[a-f0-9a-f0-9A-F0-9A-F0-9]{6,8}" $errorLog = $log | where { ($_ -match $codes) -and ($_ -notmatch "0x00000000") } if($null -eq $errorlog){ return $null } if($errorlog.length -eq 0){ return $null } if( (isarray $errorlog) ){ if($errorlog.count -gt 1){ return $errorlog[$errorlog.Count -1] }else{ return $errorlog[0] } } return $errorLog }#> #Commenting Since Function not called in any part of code - 21/04/15 # gets that last error in 8 days, code repitition because of scope creep and wanted to make it easy for testing <#function get-lastErrorin8Days(){ $log = Get-WarningAndFatalWindowsUpdateLog ($env:windir+"\windowsupdate.log") if($log -eq $null) { return $null } $lastweek = Get-DateLastWeek #filtering for lastweek events $datedLog = Get-DatedLog $lastweek $log #checking for 0x123456 or 0x12345678 codes if($datedLog -eq $null) { return $null } $str = Get-LatestWindowsUpdateErrorFromLog $datedLog return $str }#> #*================================================================================= #Function to get the Windows Event logs #GetSystemEvents #*================================================================================= function GetSystemEvents($eventSrc,$time) { $events = Get-WinEvent -ProviderName $eventsSrc | ?{($_.LevelDisplayName -ne "Information") -and (($_.Id -eq 20) -or ($_.Id -eq 25)) -and ($_.TimeCreated -gt $time)} return $events } #*================================================================================= #hasWinUpdateErrorInLastWeek #*================================================================================= function hasWinUpdateErrorInLastWeek([switch]$AllLastWeekError){ #Commented for Supporting Win 10 #$log = Get-WarningAndFatalWindowsUpdateLog ($env:windir+"\windowsupdate.log") $Events = @() $eventsSrc = "Microsoft-Windows-WindowsUpdateClient" $StartTime = (Get-Date) - (New-TimeSpan -Day 8) $wuEvents = GetSystemEvents $eventsSrc $StartTime if($wuEvents -eq $null) { return $null } #$datedLog = Get-DatedLog $lastweek $log $Events += Get-DatedEvents $wuEvents #checking for 0x123456 or 0x12345678 codes #if($datedLog -eq $null) { return $null } #$str = Get-LatestWindowsUpdateErrorFromLog $datedLog #if($str -eq $null){ return $null } #$latest = Get-ComponentAndErrorCode $str $latest = Get-ComponentAndErrorCode $Events[0] $prob1 = @{} $prob1.add("latest",$latest) if($AllLastWeekError) { foreach($str in $Events) { $ecode = Get-ComponentAndErrorCode $str if($ecode -ne $null -and !$prob1.ContainsValue($ecode)) { $prob1.add($ecode,$ecode) } } } return $prob1 } #*================================================================================= #GetAllErrorCodes #*================================================================================= function GetAllErrorCodes() { return (hasWinUpdateErrorInLastWeek -AllLastWeekError) } # register dll to fix Error code 0x800B0100 when using Windows Update or Microsoft Update to install updates # http://support.microsoft.com/kb/956702 function registerDLL_SignatureCheck(){ regsvr32 Softpub.dll /s regsvr32 Wintrust.dll /s regsvr32 Initpki.dll /s regsvr32 Mssip32.dll /s } # error code detected function ErrorDetected($errorCodetoCHeck){ $errorCodes = GetAllErrorCodes $detected = $false foreach($err in $errorCodes){ [string]$err1 = [string]$err if($err1.indexof($errorCodetoCHeck) -gt -1){ $detected = $true break } } return $detected } #function that checks whether a service is started or not function isServiceStarted($serviceName){ if($serviceName -eq $null){ return $false } $service=get-service $serviceName if($service.status -ieq "running"){ return $true } return $false } #function that checks whether given of services are started or not using isServiceStarted function function didGivenServicesStarted($services){ foreach($s in $services){ if(((isServiceStarted $s) -eq $false)){ return $false } } return $true } #*================================================================================= #CheckErrorCode #*================================================================================= function CheckErrorCode { param($errorcode,$allError) if($allError.GetType().Name -eq "Hashtable") { return $allError.Contains($errorcode) } } #====================================== # debug Information writing in file #===================================== function append-debugFile($msg1,$file1){ $msg1 >> $file1 }