16 August,2017 by Tom Collins
This Powershell script will Check on all Windows servers that a service which was meant to start has failed. Excludes services which are not meant to start.
One of the keys in a disaster recovery plan is the ability to quickly identify issues which may impact business continuity. Part of the DBA responsibility is to identify issues , fixing them and working with other engineering support staff.
The purpose of this script is to quickly scan all the servers in the list – and find services which are not 1077 or 0. In other words, the services have attempted to start but failed since the last restart.
Service Exit Code 1077 and false negatives cause extra workload in identifying the "real" issues. Using a method which quickly scan the servers and only reports on the necessary information - assists in leading to a quicker recovery.
Being prepared for a disaster recovery is essential in how to recover. What scripts do you have in place? Where are the scripts maintained? Access to passwords vaults ? etc. Thinking through what are the practical considerations for a DR .
Normally I have three main processes for a quick reporting on the current state of events. Firstly - I complete a scan of servers to identify server level connectivity , Secondly - Windows services level , such as this script Disaster Recovery Powershell Script to check for failed Windows services and thirdly , at a SQL Server database level checking for database status and database corruption ,check Post disaster recovery SQL Server database checkout script
Why use Powershell? There's some extra information on Powershell and Disaster Recovery preparation – T-SQL about some of the benefits in using Powershell for Disaster Recovery planning for the SQL Server platform
How to run the script
1)Place script in a folder
2)Within that folder create a folder called "logs" & "config"
3)All output reports will be dumped into "logs"
4)All source server lists are placed in this folder "config"
By default the "config" folder should have these files
"servers.txt" - a list of all Windows & Linux servers in scope for test
The "servers.txt" file should have a list of servers
server1
server2
server3
The security context of the user executing the script should have the relevant permissions
[cmdletbinding()] Param( [string[]]$ComputerName = $env:ComputerName ) $isodate=Get-Date -format s $isodate=$isodate -replace(":","") $basepath=(Get-Location -PSProvider FileSystem).ProviderPath $outputfile="\logs\windows_services_failed_test_" + $isodate + ".html" $outputfilefull = $basepath + $outputfile $configpath = $basepath + "\config\servers.txt" $currentuser= $env:UserDomain + "\" + $env:Username $currentcomputername = $env:ComputerName $style="" $dt = new-object "System.Data.DataTable" $col1 = New-Object system.Data.DataColumn ColumnName1,([string]) $col2 = New-Object system.Data.DataColumn ColumnName2,([string]) $dt.columns.add($col1) $dt.columns.add($col2) foreach($Computer in get-content $configpath) { if(Test-Connection -Computer $Computer -Count 1 -quiet) { try { $computer $row = $dt.NewRow() $services = Get-WMIObject -Class Win32_Service -Filter "State='Stopped'" -ComputerName $Computer -EA stop foreach($service in $services) { if(!(($service.exitcode -eq 0) -or ($service.exitcode -eq 1077))) { $Error = Invoke-Expression "net helpmsg $($service.Exitcode)" $row.ColumnName1 = $computer $row.ColumnName2 = $Service | select Name, Startmode, State, Exitcode,@{Label="Message";Expression={$Error[1]}} $dt.Rows.Add($row) } } } catch { Write-Verbose "Failed to query service status. $_" } } else { Write-Verbose "$Computer : OFFLINE" } #check completed $row = $dt.NewRow() $row.ColumnName1 = $computer $row.ColumnName2 = "Check completed" $dt.Rows.Add($row) } $dt| select * -ExcludeProperty RowError, RowState, HasErrors, Name, Table, ItemArray | ConvertTo-Html -head $style -body "Windows services failed to start . Test Date: $isodate User: $currentuser Machine: $currentcomputername " | Set-Content $outputfilefull
This is only a preview. Your comment has not yet been posted.
As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.
Having trouble reading this image? View an alternate.
Posted by: |