Archive for November, 2010

PowerShell Script Test-Automatic-Services.ps1

Project Objective:
Nagios/NRPE plugin to test if all services that are set to Automatic are indeed running (ignoring a list of services that are deemed ‘OK’). If not runing, attempt to restart the service, if the restart fails send a critical error, if the restart is successful send a warning error.

Problem to be solved:
Existing check_services.wsf Nagios plugin doesn’t have an editable array.

Suggestions:
Add array to existing wsf/vbsript plugin – REJECED
If I’m going to do that much re-writing I’d rather convert the script to PowerShell, also I appreciate how arrays are done in PowerShell more than in vbscript.

Future Versions:
I’m considering adding or replacing the error returns with Event log entries instead, though presumably they should be there already.

Notes:
There are some services that you may prefer to set to Manual instead of Automatic and vice versa instead of adding them to the ignore list.

#
# Test-Automatic-Services.ps1
#
# Written by Aaron Wurthmann (aaron (AT) wurthmann (DOT) com)
#
# If you edit please keep my name as an original author and
# keep me apprised of the changes, see email address above.
# This code may not be used for commercial purposes.
# You the executor, runner, user accept all liability.
# This code comes with ABSOLUTELY NO WARRANTY.
# You may redistribute copies of the code under the terms of the GPL v2.
# -----------------------------------------------------------------------
# 2010.11.09 ver 2.0
#
# Summary:
# Checks services set to Automatic and insures they are running.
# Ignores an array of services such as Performance Logs and Alerts
# which are set to Automatic but turns themselves off.
#
# If an Automatic service is not Running and not in the Ignore array
# an attempt to restart the service is made. If the service is restarted
# a Warning is returned. If the service could not be restarted a
# Critical error is returned.
# -----------------------------------------------------------------------
# Usage:
# This script does not require any input parameters.
#    For Nagios NRPE/NSClient++ usage add the following line to the
#    NSC.ini file after placing this script in Scripts subdirectory.
#    check_services=cmd /c echo scriptsTest-Automatic-Services.ps1; exit($lastexitcode) | powershell.exe -command -
#    NOTE: The trailing - is required.
# -----------------------------------------------------------------------
# Orgin:
# This script (or one like it) was originally written by ronald van vugt
#     (ronald.van.vugt@vanderlet.nl)
# I took the vbscriptwsf version that he wrote and converted it to
# PowerShell while adding an array of ignored services and making other
# slight improvements such as adjusting the WMI query to only return
# stopped services.
# -----------------------------------------------------------------------
# Notes:
# Unlike the majority of my scripts this script has rather verbose
# comments in it. This is both to pay homage to the original author as
# well as to aid others with learning PowerShell. The original version
# of this script, the vbscript/wsf version was a vbscript learning
# experience for myself and the basis of my vbscripts to follow.
# -----------------------------------------------------------------------

# Varibles used to caluclate number and type of errors if any.
[int]$intResultWarning = 0
[int]$intResultError = 0
[int]$intResultTotal = 0

# List of Services to Ignore.
$Ignore=@(
    'Microsoft .NET Framework NGEN v4.0.30319_X64',
    'Microsoft .NET Framework NGEN v4.0.30319_X86',
    'Multimedia Class Scheduler',
    'Performance Logs and Alerts',
    'SBSD Security Center Service',
    'Shell Hardware Detection',
    'Software Protection',
    'TPM Base Services';
)

# Get list of services that are not running, not in the ignore list and set to automatic
$Services=Get-WmiObject Win32_Service | Where {$_.StartMode -eq 'Auto' -and $Ignore -notcontains $_.DisplayName -and $_.State -ne 'Running'}

# If any services were found fitting the above description...
if ($Services) {
    # Loop through each service in services
    ForEach ($Service in $Services) {
        # Attempt to restart the service
        $err = $Service.StartService()
        # Pause for 1 second
        Start-Sleep -s 1
        # Re-Get the Service information in order to recheck its status
        $StoppedService=Get-Service -Displayname $Service.Displayname
        # If the service failed to restart...
        If ($StoppedService.Status -ne 'Running') {
            # Set the error level to 2 (critical)
            $intResultError = 2
            # If this is not the first recorded error amend the error text
            if ($strResultError) {
                $strResultError=$strResultError + ', ' + $Service.Displayname
            }
            # If this is the first or only error set error text
            ELSE {
                $strResultError = 'Services failed after restart: ' + $Service.Displayname
            }
        }
        ELSE {
            # If the service restarted set the warning error level to 1 (warning)
            $intResultWarning = 1
            # If this is not the first recorded error amend the error text
            if ($strResultWarning) {
            $strResultWarning=$strResultWarning + ', ' + $Service.Displayname
            }
            # If this is the first or only error set error text
            ELSE {
                $strResultWarning = 'Services restarted: ' + $Service.Displayname
            }
        }
        # Clear the StoppedService varible
        if ($StoppedService) {Clear-Variable StoppedService}
    }
}

# Add the warning error (0 or 1) to the critical error (0 or 2)
$intResultTotal=$intResultWarning + $intResultError

# Using the sum of the warning errors to the critical errors select the appropriate response
Switch ($intResultTotal) {
    # Default/no errors
    default {
        write-host 'All automatic started services are running'
        exit 0
    }
    # Warning error(s) only
    1 {
        write-host $strResultWarning
        exit 1
    }
    # Critical error(s) only
    2 {
        write-host $strResultError
        exit 2
    }
    # Critical and Warning errors
    3 {
        write-host $strResultError
        write-host $strResultWarning
        exit 2
    }
}

Batch Script Add-DNS-Forwarders.bat

Project Objective:
We have multiple Windows DNS servers that need a forwarder configured for a specific domain.

Problem to be solved:
This is normally a setting that needs to be configured by hand on each DNS server.

@echo off

rem #***********************************************************************
rem # "Add-DNS-Forwarders.bat"
rem #
rem # Written by Aaron Wurthmann (aaron (AT) wurthmann (DOT) com)
rem # If you edit please keep my name as an original author and
rem # keep me apprised of the changes, see email address above.
rem # This code may not be used for commercial purposes.
rem # You the executor,runner,user accept all liability.
rem # This code comes with ABSOLUTELY NO WARRANTY.
rem # You may redistribute copies of the code under the terms of the GPL v2.
rem # -----------------------------------------------------------------------
rem # 2010.11.02 ver FINAL
rem #
rem # Summary:
rem # Creates conditional DNS forwards for domains.
rem # Be sure to adjust your settings below as needed.
rem #************************************************************************

rem    DNS Servers to contact/run against
set DNSserver1=192.168.1.100
set DNSserver2=192.168.1.101

rem    Conditional Zone to Forward For
set Zone=domain.ext

rem    DNS Forwards to contact for Conditional Zone seperated with a single space
set Forwarders=192.168.2.100 192.168.2.101

rem    Main
FOR /F "usebackq tokens=2 delims==" %%i IN (`set DNSserver`) DO (
    dnscmd %%i /zoneadd %Zone% /forwarder %Forwarders%
)