Functions/Get-BcServerInstance.ps1

<#
.SYNOPSIS
    Gets service details for all or the specified Business Central Server instance.
.DESCRIPTION
    Use the Get-FpsBCServerInstance cmdlet to obtain service details for all or the specified Business Central Server instance.
     
    When not a service instance is provided all instances of all versions for the specific machine is returned.
    With VersionFilter, StateFilter and ExcludeServerInstance the returned list can be filtered.
.EXAMPLE
    Get-FpsBCServerInstance
.EXAMPLE
    Get-FpsBCServerInstance -Computer 'remote.domain.eu'
.EXAMPLE
    Get-FpsBCServerInstance -ServiceInstance 'BC150'
.EXAMPLE
    Get-FpsBCServerInstance -Computer @('DevSrv01', 'DevSrv02', 'DevSrv03') -VersionFilter '21'
.EXAMPLE
    # Returns all BC21 service instances with a running service state, excluding the BC210 service.
    Get-FpsBCServerInstance -VersionFilter '21' -StateFilter Running -ExcludeServerInstance 'BC210'
#>

function Get-BCServerInstance {
    [CmdletBinding(DefaultParameterSetName='All Instances')]
    Param (
        [Parameter(ValueFromPipeline=$true, ParameterSetName='Specific Instance')]
        [string[]] $ServerInstance,

        [Parameter(ParameterSetName='All Instances')]
        [string] $VersionFilter,

        [Parameter(ParameterSetName='All Instances')]
        [ValidateSet("Running", "Stopped", "Starting", "Stopping", "All")]
        [string] $StateFilter = "All",

        [Parameter(ParameterSetName='All Instances')]
        [ValidateSet("Auto", "Manual", "Disabled", "All")]
        [string] $StartModeFilter = 'All',

        [Parameter(ParameterSetName='All Instances')]
        [string[]] $ExcludeServerInstance,

        [Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName='Specific Instance')]
        [Parameter(ValueFromPipelineByPropertyName = $true, ParameterSetName='All Instances')]
        [string[]] $Computer = $env:COMPUTERNAME
    )
    
    begin {
        if([string]::IsNullOrEmpty($ServerInstance)){
            $allServerInstances = $true
        }
        
        $results = @()

        [scriptblock] $ScriptBlock = {
            param(
                $ServerInstance,
                $AllServerInstances,
                $VersionFilter,
                $StateFilter,
                $StartModeFilter,
                $ExcludeServerInstance
            )

            function Get-ServiceVersion {
                param(
                    [Parameter(ValueFromPipeline=$true, Mandatory=$true)]
                    [System.Management.ManagementBaseObject] $Service
                )

                $Regex = '.*"(?<ServicePath>.*?.exe)".*'
                $Match = $Service.PathName | Select-String -Pattern $Regex
                $ExecutablePath = $Match.Matches[0].Groups['ServicePath'].Value
                
                if((Test-Path $ExecutablePath)){
                    [version] $ExecutableVersion = (Get-Item $ExecutablePath).VersionInfo.FileVersion
                } else {
                    Write-Warning ('The Business Central installation is not found for Server Instance ''{0}'' on location: {1}' -f 
                        ($Service.Name.Split('$'))[1], $ExecutablePath)
                    return [version] '0.0.0.0'
                }
                return $ExecutableVersion
            }
            
            $results = @()

            # Get Business Central Service Instances
            $bcServices = @()

            if($ServerInstance){
                foreach ($Instance in $ServerInstance){
                    $bcServices += Get-WmiObject win32_service | Where-Object Name -like ('MicrosoftDynamicsNavServer`${0}' -f $Instance)
                }
            } 
            elseif($AllServerInstances){
                $bcServices = Get-WmiObject win32_service | Where-Object Name -like 'MicrosoftDynamicsNavServer*'
            }

            # Apply Exclude filter
            if($ExcludeServerInstance){
                $bcServices = $bcServices | ForEach-Object {
                    if($_.Name -notin $ExcludeServerInstance -and $_.Name.Split('$')[1] -notin $ExcludeServerInstance){
                        $_
                    }
                }
            }

            # Apply version filter
            if($VersionFilter){
                $bcServices = $bcServices | ForEach-Object {
                    $ServiceVersion = ($_ | Get-ServiceVersion).ToString()
                    if($ServiceVersion -like ('{0}*' -f $VersionFilter)){
                        $_
                    }
                }
            }

            # Apply start-up type filter
            if($StartModeFilter -and $StartModeFilter -ne 'All'){
                $bcServices = $bcServices | ForEach-Object {
                    if($_.StartMode -eq $StartModeFilter){
                        $_
                    }
                }
            }
            
            # Apply State filter
            if($StateFilter -and $StateFilter -ne 'All'){
                $bcServices = $bcServices | ForEach-Object {
                    if($_.State -eq $StateFilter){
                        $_
                    }
                }            
            }

            if($bcServices.count -eq 0){
                'No Server Instance found. Make sure the Server Instance exists and is not exluded with the set filters.' | Write-Warning
                return
            }

            foreach ($service in $BcServices){
                $results += @{
                    'Service'  = $service.Name
                    'Computer' = $env:COMPUTERNAME
                }
            }

            return $results
        }
    }
    
    process {
        foreach ($server in $Computer){
            
            $additionParams = @{}
            if ($server -ne 'localhost' -and $c -ne $env:COMPUTERNAME) {
                $additionParams = @{'ComputerName' = $server}
            }
            
            $result = Invoke-Command @additionParams -ScriptBlock $scriptBlock -ArgumentList `
                $ServerInstance,
                $AllServerInstances,
                $VersionFilter,
                $StateFilter,
                $StartModeFilter,
                $ExcludeServerInstance

            $result | ForEach-Object {
                $results += [BcServerInstance]::new($_.Service, $_.Computer)
            }
        }
    }
    end {
        return $results
    }
}
Export-ModuleMember -Function Get-BCServerInstance