Thursday, May 11, 2017

Powershell script to recycle a list of services

This script will stop a set of services in the order given and then start them again in the reverse order.

<#
.Synopsis
    Recycle-Services.ps1 - Stops a list of services and restarts them again

.DESCRIPTION
    This script will stop a given list of services, in the order given,
    then start the services again in the reverse order.

    While stopping the services it will disable them to prevent other automation
    from restarting them prematurely.  When restarting the services it will set
    their startup type to "Automatic".

    Script by Mark Randol - randoltech.blogspot.com

.USAGE
    Change the line that has
        [String[]]$ServiceNames =
    to include whatever services you need restarted. You can add as many as you like
    just be sure to enclose the service names in quotations and seperate them with commas

    Example:
        [String[]]$ServiceNames = "Audiosrv","MyService","SUMDUMSERVICE"

#>

function Wait-ServiceState{
    [CmdletBinding()]
    [OutputType([int])]
    Param(
        [Parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true)]
        [Alias('Service','ServiceNames')][String[]] $Service2WaitFor,
        [Parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true)]
        [String[]] $State
    )
    Process{
        $maxRepeat = 120 #Number of half seconds
        do
        {
            $CurrentStatus = (Get-Service $Service2WaitFor).Status
            $maxRepeat--
            sleep -Milliseconds 500
        } until ($CurrentStatus -eq $State -or $maxRepeat -eq 0)
        Return $maxRepeat
    }
} #Waits until service is in specified state or a specified amount of time has elapsed, whichever comes first

function Stop-MyService{
    [CmdletBinding()]
    [OutputType([String])]
    Param(
        [Parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true)]
        [Alias('Service','ServiceNames')][String] $Service2Stop
    )
    Process{
        If (Get-Service $Service2Stop -ErrorAction Stop){
            If ((Get-Service $Service2Stop).StartType -ne 'Disabled') {Set-Service -Name $Service2Stop -StartupType Disabled -ErrorAction Stop}
            If ((Get-Service $Service2Stop).Status -ne 'Stopped') {Stop-Service -Name $Service2Stop -ErrorAction Continue}
            $StoppedService = (Wait-ServiceState -Service2WaitFor $Service2Stop -State Stopped -ErrorAction Stop)
        }
        If ($StoppedService -ne 0){
            $OutputString = "$Service2Stop successfully stopped."
            Return $OutputString
        }
        else{
            $OutputString = "Unable to stop $Service2Stop"
            Return $OutputString
        }
    }
} #Sets the service to disabled and stops it.

function Start-MyService{
    [CmdletBinding()]
    [OutputType([String])]
    Param(
        [Parameter(Position=0, Mandatory=$true, ValueFromPipelineByPropertyName=$true, ValueFromPipeline=$true)]
        [Alias('Service','ServiceNames')][String] $Service2Start
    )
    Process{
        If (Get-Service $Service2Start -ErrorAction Stop){
            If ((Get-Service $Service2Start).StartType -ne 'Automatic') {Set-Service -Name $Service2Start -StartupType Automatic -ErrorAction Stop}
            If ((Get-Service $Service2Start).Status -ne 'Running') {Start-Service $Service2Start -ErrorAction Continue}
            $StartedService = (Wait-ServiceState -Service2WaitFor $Service2Start -State Running -ErrorAction Stop)
        }
        If ($StartedService -ne 0){
            $OutputString = "$Service2Start successfully started."
            Return $OutputString
        }
        else{
            $OutputString = "Unable to start $Service2Start"
            Return $OutputString
        }
    }
} #Sets the service to automatic and starts it.

[String[]]$ServiceNames = "MyService","SUMDUMSERVICE"
[int]$ServiceNum = 0
[string]$Service = ""

#Stop the services
do{
    $Service = $ServiceNames[$ServiceNum]     Write-Output ("Stopping $Service")
    $Stopped = (Stop-MyService -Service2Stop $Service)
    $SuccessString = "$Service successfully stopped."
    Write-Output $Stopped
    iF ($Stopped -ne $SuccessString){
        Return $Stopped
    }
    $ServiceNum ++
} #Stop the services in the order given
while ($ServiceNum -lt $ServiceNames.Count)


#Start the services
$ServiceNum = $ServiceNames.Count - 1

do{
    $Service = $ServiceNames[$ServiceNum]
    Write-Output ("Starting $Service")
    $Started = (Start-MyService -Service2Start $Service)
    $SuccessString = "$Service successfully started."
    Write-Output $Started
    iF ($Started -ne $SuccessString){
        Return $Started
    }
    $ServiceNum --
} #Start the services in reverse order
while ($ServiceNum -gt -1)

$OutputString = "0"
Return $OutputString