ServiceState.psm1

function Set-ServiceState {
    [CmdletBinding()]
    [OutputType([int])]
    param
    (
        # Location of CSV file containing the state of services!>
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
        $CSVLocation = "C:\Temp\Services-test.csv",

        # Retry count
        [int]$TryCount = 5)

        # Test if file exists

        if (Test-Path $CSVLocation) {
            Write-Verbose "Importing CSV file"
        }
        else {
            Write-Host "Check if CSV file $CSVLocation exist!!!" -ForegroundColor Red
            break
        }

        # imports CSV file
        $DashBoard = Import-Csv -Path $CSVLocation

        # Build a list of server names
        $ServerList = $DashBoard.'Server name' | Select-Object -Unique

        # Opens an empty arry for storing information about services that failed to return to origional state
        $ServiceStatus = @()


        foreach ($Server in $ServerList) {

            Write-Verbose "Working with $Server" -Verbose

            # Builds a service list per server
            $ServiceList = $DashBoard | Where-Object {$_.'Server name' -EQ $Server}

            # loops thrugh each service and trys to return it to origional state
            foreach ($Service in $ServiceList) {

                # Removes " that are around service name.
                $Srvc = $Service.'Service Name' -replace '"', ""

                # making sure that the service is in desired state as in CSV file
                If ((Get-Service -ComputerName $Server -Name $Srvc -ErrorAction SilentlyContinue).Status -eq $Service.Status) {
                    Write-Host Service $Srvc on $Server is in its correct state $Service.Status

                }
                Else {
                    if ($Service.Status -eq 'Running') {
                        Write-Host Service $Srvc on $Server is in WRONG state. Should be $Service.Status -BackgroundColor DarkRed
                        Write-Host Starting $Srvc on $Server. -BackgroundColor DarkGreen
                            
                        $i = 1
                        Do {
                            Write-Host Try $i : Starting $Srvc on $Server. -BackgroundColor DarkGreen
                            Get-Service -ComputerName $Server -Name $Srvc -ErrorAction SilentlyContinue | Start-Service -ErrorVariable ErrorMessage -ErrorAction SilentlyContinue ; $i++
                        }
                        Until ($i -gt $TryCount -or (Get-Service -ComputerName $Server -Name $Srvc -ErrorAction SilentlyContinue).status -eq $Service.Status)
                                
                        If (!(Get-Service -ComputerName $Server -Name $Srvc -ErrorAction SilentlyContinue).status -eq $Service.Status) {
                          

                            Write-Host "Failed to start $Srvc on $Server with error message: $ErrorMessage"


                            $ObjServiceStatus = New-Object System.Object
                            $ObjServiceStatus | Add-Member -type NoteProperty -name ServerName -value $Server
                            $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceName -value $Service.'Service Name'
                            $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceSatus -value (Get-Service -ComputerName $Server -Name $Srvc -ErrorAction SilentlyContinue).status
                            $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceShouldBe -value $Service.Status


                            $ServiceStatus += $ObjServiceStatus




                        }
                       




                    }
                    else {
                        Write-Host Service $Srvc on $Server is in WRONG state. Should be $Service.Status -BackgroundColor DarkRed
                        Write-Host Stopping $Srvc on $Server. -BackgroundColor DarkGreen
                        

                        $i = 1
                        Do {
                            Write-Host Try $i : Stopping $Srvc on $Server. -BackgroundColor DarkGreen
                            Get-Service -ComputerName $Server -Name $Srvc -ErrorAction SilentlyContinue | Stop-Service -ErrorVariable ErrorMessage -ErrorAction SilentlyContinue ; $i++
                        }
                        Until ($i -gt $TryCount -or (Get-Service -ComputerName $Server -Name $Srvc -ErrorAction SilentlyContinue).status -eq $Service.Status)
                                
                        If (!(Get-Service -ComputerName $Server -Name $Srvc -ErrorAction SilentlyContinue).status -eq $Service.Status) {
                          

                            Write-Host "Failed to stop $Srvc on $Server with error message: $ErrorMessage"


                            $ObjServiceStatus = New-Object System.Object
                            $ObjServiceStatus | Add-Member -type NoteProperty -name ServerName -value $Server
                            $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceName -value $Service.'Service Name'
                            $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceSatus -value (Get-Service -ComputerName $Server -Name $Srvc -ErrorAction SilentlyContinue).status
                            $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceShouldBe -value $Service.Status


                            $ServiceStatus += $ObjServiceStatus



                        }
                
                    }
                }

            }



        }

        If (!([string]::IsNullOrEmpty($ServiceStatus))) {

        Write-Host "The following list contains servers and services that failed to return to origional state " -BackgroundColor Red
        Write-host ($ServiceStatus |Format-Table | Out-String )
        }
}

function Get-ServiceState {
    [CmdletBinding()]
    [OutputType([int])]
    param
    (
        # Location of CSV file containing the state of services
        [Parameter(Mandatory = $true, ValueFromPipelineByPropertyName = $true, Position = 0)]
        $CSVLocation = "D:\Temp\Services.csv"
    )

    # Test if file exists

    if (Test-Path $CSVLocation) {
        Write-Verbose "Importing CSV file"
    }
    else {
        Write-Verbose "Check if CSV file $CSVLocation exist."
        break
    }

    # imports CSV file
    $DashBoard = Import-Csv -Path $CSVLocation

    # Build a list of server names
    $ServerList = $DashBoard.'Server name' | Select-Object -Unique

    # Opens an empty arry for storing information about services
    $ServiceStatus = @()
    $ServiceStatusUnknown = @()
          

    foreach ($Server in $ServerList) {

        Write-Verbose "Working on $Server"

        # Builds a service list per server
        $ServiceList = $DashBoard | Where-Object {$_.'Server name' -EQ $Server}

        # loops thrugh each service and records the state of the service
        foreach ($Service in $ServiceList) {

            # Removes quoates that are around service name.
            $Srvc = $Service.'Service Name' -replace '"', ""

             # Get service state for the incoming service
            try {
                $LiveServiceState = Get-Service -ComputerName $Server -Name $Srvc -ErrorAction SilentlyContinue
            }
            catch {
                Write-Verbose ( "{0} : {1}" -f $Server, $_.Exception.Message )
                Continue
            }

                

            If ($LiveServiceState.Status -ne $Service.Status -and $LiveServiceState.Status.count -gt 0) {
                Write-Verbose ("Service {0} on {1} is in WRONG state. Should be {2}" -f $Srvc, $Server, $Service.Status)

                $ObjServiceStatus = New-Object System.Object
                $ObjServiceStatus | Add-Member -type NoteProperty -name ServerName -value $Server
                $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceName -value $Service.'Service Name'
                $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceStatus -value ($LiveServiceState).status
                $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceShouldBe -value $Service.Status

                $ServiceStatus += $ObjServiceStatus
            }

            elseif (([string]::IsNullOrEmpty($LiveServiceState))){
                Write-Host ("Could not determine the state of {0} on {1}" -f $Srvc, $Server) -BackgroundColor Red
                
                $ObjServiceStatus = New-Object System.Object
                $ObjServiceStatus | Add-Member -type NoteProperty -name ServerName -value $Server
                $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceName -value $Service.'Service Name'
                $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceStatus -value ($LiveServiceState).status
                $ObjServiceStatus | Add-Member -type NoteProperty -name ServiceShouldBe -value $Service.Status

                $ServiceStatusUnknown += $ObjServiceStatus

            }

            else {
                Write-Verbose ("Service {0} on {1} is in its correct state {2}" -f $Srvc, $Server, $Service.Status)
            }
                    
                    

        }



    }

            
    If (!([string]::IsNullOrEmpty($ServiceStatus))) {

        Write-Host "The following services are in the wrong state:" -BackgroundColor Red
        Write-host ($ServiceStatus |Format-Table | Out-String )


    }

    if (!([string]::IsNullOrEmpty($ServiceStatusUnknown))) {

        Write-Host "Could not retrieve the status of the following services:" -BackgroundColor Red
        Write-host ($ServiceStatusUnknown |Format-Table | Out-String )
        }

    if ([string]::IsNullOrEmpty($ServiceStatus) -and [string]::IsNullOrEmpty($ServiceStatusUnknown)) {
              
        Write-Host "Services are in desired state! Have a good day!" -ForegroundColor Green
    }

            
}

function Get-History {
    [CmdletBinding()]
    [OutputType([int])]
    param
    (
        # Location of the archive root folder
        $CSVArchiveLocation = "\\localhost\D$\Git\DevOps\PSModules\ServiceState\ExampleCSV",
        # The name of the environemnt
        [string]$environment
    )

        if (Test-Path (Join-Path $CSVArchiveLocation $environment ) ) {
        Write-Verbose "Importing CSV file"
    }
    else {
        Write-Verbose "Check if CSV file $CSVLocation exist."
        break
    }
}