# processWatcher.ps1

# User Input
$computername=$env:computername
$serviceName='remoteregistry'
$desiredStatus='Running'

$action={
    param($serviceName)
    $erroractionpreference='stop'
    try{
        start-service $serviceName
        return $true
    }catch{
        write-host $_
        return $false
    }
}

function watchProcess($computername=$env:computername,$servicename,$desiredStatus,$action){
    function checkService($computername,$serviceName,$status='Running'){
        # Sanitation
        #$invalidChars=$processName.IndexOfAny([System.IO.Path]::GetInvalidFileNameChars())
        $systemInvalidChars =[Regex]::Escape(-join [System.Io.Path]::GetInvalidFileNameChars())
        $regexInvalidChars = "[$systemInvalidChars]"
        $serviceName=$serviceName -replace [regex]::Matches($serviceName, $regexInvalidChars, 'IgnoreCase').Value
        if($desiredStatus -ne 'Stopped'){
            $desiredStatus='Running'
        }
        try{
            $service=get-service -name $serviceName -ComputerName $computername|select -first 1
            if($service.Status -eq $status){
                write-host "status matches the desired state" -foregroundcolor Green
                return 0
            }elseif($null -ne $service.Status){
                write-host "status doesn`'t match the desired state" -foregroundcolor Red
                return 1
            }else{
                write-host "$serviceName was not found" -foregroundcolor Red
                return -1          
            }
        }catch{
            Write-Error $_
            write-host "$serviceName was not found" -foregroundcolor Red
            return -1
        }
    }
    $serviceStatusCode=checkService $computername $serviceName $desiredStatus
    if ($serviceStatusCode -eq 0){
        write-host "$serviceName is healthy. No actions required." -foregroundcolor Green
        return $true
    }elseif($serviceStatusCode -eq 1){
        $success=invoke-command -ComputerName $computername -scriptblock $action -Args $serviceName
        return $success
    }else{
        write-host "There appears to be a problem with the service status code of $serviceStatusCode"
        return $false
    }
}

watchProcess $computername $servicename $desiredStatus
# Previous iterations of process watcher for a CRM Environment

$serviceName='MSCRMAsyncService$maintenance'
$desiredStatus='Running'
$environment=($env:computername).substring(0,$env:computername.IndexOf('-'))
$reportServer="$environment-SQL01"

function checkService($computername=$env:computername,$serviceName,$status='Running'){
    # Sanitation
    #$invalidChars=$processName.IndexOfAny([System.IO.Path]::GetInvalidFileNameChars())
    $systemInvalidChars =[Regex]::Escape(-join [System.Io.Path]::GetInvalidFileNameChars())
    $regexInvalidChars = "[$systemInvalidChars]"
    $serviceName=$serviceName -replace [regex]::Matches($serviceName, $regexInvalidChars, 'IgnoreCase').Value
    if($desiredStatus -ne 'Stopped'){
        $desiredStatus='Running'
    }
    try{
        $service=get-service -name $serviceName -ComputerName $computername|select -first 1
        if($service.Status -eq $status){
            write-host "status matches the desired state" -foregroundcolor Green
            return 0
        }elseif($null -ne $service.Status){
            write-host "status doesn`'t match the desired state" -foregroundcolor Red
            return 1
        }else{
            write-host "$serviceName was not found" -foregroundcolor Red
            return -1          
        }
    }catch{
        Write-Error $_
        write-host "$serviceName was not found" -foregroundcolor Red
        return -1
    }
}

$action={
        $erroractionpreference='stop'
        try{
            $crmTools=if(test-path "$env:programfiles\dynamics 365"){"$env:programfiles\dynamics 365\Tools"
                }else{"$env:programfiles\Microsoft Dynamics CRM\Tools"}
            write-host 'Restarting Microsoft Dynamics CRM Asynchronous Services...'
            get-service|?{$_.name -like 'MSCRMAsyncService*'}|restart-service
            write-host 'Renewing keys to CRM App server...'
            & "$crmTools\Microsoft.Crm.Tools.WRPCKeyRenewal.exe" /R
            if($LASTEXITCODE -ne 0){
                write-host 'Microsoft.Crm.Tools.WRPCKeyRenewal.exe command failed.'
                $result=$false
            }else{
                sleep 3
                write-host 'Restarting Microsoft Dynamics CRM Asynchronous Service (maintenance)...'
                get-service|?{$_.DisplayName -like 'Microsoft Dynamics*(maintenance)'}|restart-service
                $result=$true
                }
            return $result
        }catch{
            write-host $_
            return $false
        }
    }
function performAction($serviceStatusCode,$action){
    if ($serviceStatusCode -eq 0){
        write-host "$serviceName is healthy. No actions required." -foregroundcolor Green
        return $true
    }elseif($serviceStatusCode -eq 1){
        $success=invoke-command -ComputerName $reportServer -scriptblock $action
        return $success
    }else{
        write-host 'There appears to be a problem with the service status code of $serviceStatusCode'
        return $false
    }
}

$serviceStatusCode=checkService $reportServer $serviceName $desiredStatus
performAction $serviceStatusCode $action