Skip to content
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
Show all changes
31 commits
Select commit Hold shift + click to select a range
3f28687
Initial plan
Copilot Jul 10, 2025
c6c92c4
Add Get-SqlDscServerProtocol public command with CIM and SMO support
Copilot Jul 10, 2025
6cff221
Merge branch 'main' into copilot/fix-573e03dc-fd5a-4b2c-bee5-e2c7a757…
johlju Sep 12, 2025
2cfee78
Remove CIM functionality and refactor Get-SqlDscServerProtocol to use…
Copilot Sep 12, 2025
f49f1a4
Add Get-SqlDscServerProtocolName command and enhance Get-SqlDscServer…
Copilot Sep 12, 2025
0b368eb
Address PR feedback: Add new commands, fix parameter sets, error hand…
Copilot Sep 12, 2025
42f21fc
Address PR feedback: Fix variable casing, remove unused code, update …
Copilot Sep 12, 2025
63ca2cc
Fix formatting and add suppression message for Get-SqlDscServerProtoc…
johlju Sep 12, 2025
8727349
Merge branch 'main' into copilot/fix-573e03dc-fd5a-4b2c-bee5-e2c7a757…
johlju Sep 12, 2025
bc0c1ba
Fix error message in Get-SqlDscServerProtocol function to use correct…
johlju Sep 12, 2025
31124a0
Refactor tests to unify module name variable and enhance localized st…
johlju Sep 12, 2025
9dd30e3
Add integration tests for Get-SqlDscManagedComputerInstance, Get-SqlD…
johlju Sep 12, 2025
4c7b7c5
Remove mandatory parameter from Get-SqlDscServerProtocol function and…
johlju Sep 12, 2025
f0645f8
Re-add and enhance documentation for Get-SqlDscServerProtocol, Get-Sq…
johlju Sep 12, 2025
693ceb6
Enhance parameter type for ManagedComputerObject in Get-SqlDscManaged…
johlju Sep 12, 2025
2128c50
Remove redundant test for non-existent protocol in Get-SqlDscServerPr…
johlju Sep 12, 2025
f8f6c02
Refactor Get-SqlDscManagedComputerInstance tests to use ServerInstanc…
johlju Sep 12, 2025
ef18634
Deprecate Get-ProtocolNameProperties function and add removal notice
johlju Sep 12, 2025
df1b732
Remove deprecated notes and handle empty server protocol case in Get-…
johlju Sep 12, 2025
f117c72
Remove redundant comment for Get-SqlDscServerProtocol section in SqlS…
johlju Sep 12, 2025
71d5c86
Add validation for expected result count in Get-SqlDscManagedComputer…
johlju Sep 12, 2025
622cfa2
Fix type assertion for Get-SqlDscManagedComputerInstance results to u…
johlju Sep 12, 2025
99401dc
Update type assertion in Get-SqlDscServerProtocol tests to use Server…
johlju Sep 12, 2025
2d78fe4
Fix type assertion for Get-SqlDscServerProtocolName test to use corre…
johlju Sep 12, 2025
922046f
Update Get-SqlDscServerProtocol tests to suppress result assignment a…
johlju Sep 12, 2025
a32c295
Fix type assertion in Get-SqlDscServerProtocol tests to use ServerPro…
johlju Sep 13, 2025
96b2128
Fix type assertion in Get-SqlDscServerProtocolName test to use correc…
johlju Sep 13, 2025
8be8c6d
Implement IEnumerable interface in ServerProtocolCollection and make …
johlju Sep 13, 2025
6d588c3
Enhance error handling in Get-SqlDscServerProtocol by adding ErrorAct…
johlju Sep 13, 2025
06e8f53
Clarify guidelines for using $ErrorActionPreference by specifying to …
johlju Sep 13, 2025
edef06e
Fix missing newline at end of Get-SqlDscServerProtocolName.Tests.ps1
johlju Sep 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 95 additions & 0 deletions source/Public/Get-SqlDscServerProtocol.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
<#
.SYNOPSIS
Returns server protocol information for a SQL Server instance.
.DESCRIPTION
Returns server protocol information for a SQL Server instance using
SMO (SQL Server Management Objects). The command supports getting
information for TcpIp, NamedPipes, and SharedMemory protocols.
.PARAMETER ServerName
Specifies the name of the server where the SQL Server instance is running.
Defaults to the local computer name.
.PARAMETER InstanceName
Specifies the name of the SQL Server instance for which to return protocol
information.
.PARAMETER ProtocolName
Specifies the name of the network protocol to return information for.
Valid values are 'TcpIp', 'NamedPipes', and 'SharedMemory'.
.EXAMPLE
Get-SqlDscServerProtocol -InstanceName 'MSSQLSERVER' -ProtocolName 'TcpIp'
Returns TcpIp protocol information for the default SQL Server instance
on the local computer.
.EXAMPLE
Get-SqlDscServerProtocol -ServerName 'MyServer' -InstanceName 'MyInstance' -ProtocolName 'NamedPipes'
Returns NamedPipes protocol information for the MyInstance SQL Server
instance on the MyServer computer.
.EXAMPLE
Get-SqlDscServerProtocol -InstanceName 'MSSQLSERVER' -ProtocolName 'SharedMemory'
Returns SharedMemory protocol information for the default SQL Server
instance.
.OUTPUTS
System.Object
.NOTES
This command uses SMO (SQL Server Management Objects) to retrieve server
protocol information from the specified SQL Server instance.
#>
function Get-SqlDscServerProtocol
{
[CmdletBinding()]
param
(
[Parameter()]
[ValidateNotNullOrEmpty()]
[System.String]
$ServerName = (Get-ComputerName),

[Parameter(Mandatory = $true)]
[ValidateNotNullOrEmpty()]
[System.String]
$InstanceName,

[Parameter(Mandatory = $true)]
[ValidateSet('TcpIp', 'NamedPipes', 'SharedMemory')]
[System.String]
$ProtocolName
)

Write-Verbose -Message (
$script:localizedData.ServerProtocol_GetState -f $ProtocolName, $InstanceName, $ServerName
)

$managedComputerObject = Get-SqlDscManagedComputer -ServerName $ServerName

$serverInstance = $managedComputerObject.ServerInstances[$InstanceName]

if ($serverInstance)
{
$protocolNameProperties = Get-ProtocolNameProperties -ProtocolName $ProtocolName

$serverProtocolObject = $serverInstance.ServerProtocols[$protocolNameProperties.Name]

if (-not $serverProtocolObject)
{
$errorMessage = $script:localizedData.ServerProtocol_ProtocolNotFound -f $ProtocolName, $InstanceName, $ServerName
New-InvalidOperationException -Message $errorMessage
}
}
else
{
$errorMessage = $script:localizedData.ServerProtocol_InstanceNotFound -f $InstanceName, $ServerName
New-InvalidOperationException -Message $errorMessage
}

return $serverProtocolObject
}
5 changes: 5 additions & 0 deletions source/en-US/SqlServerDsc.strings.psd1
Original file line number Diff line number Diff line change
Expand Up @@ -288,6 +288,11 @@ ConvertFrom-StringData @'
ConvertTo_EditionName_ConvertingEditionId = Converting EditionId '{0}' to Edition name.
ConvertTo_EditionName_UnknownEditionId = The EditionId '{0}' is unknown and could not be converted.

## Get-SqlDscServerProtocol
ServerProtocol_GetState = Getting server protocol '{0}' information for instance '{1}' on server '{2}'.
ServerProtocol_ProtocolNotFound = Could not find server protocol '{0}' for instance '{1}' on server '{2}'.
ServerProtocol_InstanceNotFound = Could not find SQL Server instance '{0}' on server '{1}'.

## Assert-SqlDscLogin
Assert_Login_CheckingLogin = Checking if the principal '{0}' exists as a login on the instance '{1}'.
Assert_Login_LoginMissing = The principal '{0}' does not exist as a login on the instance '{1}'.
Expand Down
240 changes: 240 additions & 0 deletions tests/Unit/Public/Get-SqlDscServerProtocol.Tests.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,240 @@
[System.Diagnostics.CodeAnalysis.SuppressMessageAttribute('PSUseDeclaredVarsMoreThanAssignments', '')]
param ()

BeforeDiscovery {
try
{
if (-not (Get-Module -Name 'DscResource.Test'))
{
# Assumes dependencies has been resolved, so if this module is not available, run 'noop' task.
if (-not (Get-Module -Name 'DscResource.Test' -ListAvailable))
{
# Redirect all streams to $null, except the error stream (stream 2)
& "$PSScriptRoot/../../../build.ps1" -Tasks 'noop' 3>&1 4>&1 5>&1 6>&1 > $null
}

# If the dependencies has not been resolved, this will throw an error.
Import-Module -Name 'DscResource.Test' -Force -ErrorAction 'Stop'
}
}
catch [System.IO.FileNotFoundException]
{
throw 'DscResource.Test module dependency not found. Please run ".\build.ps1 -ResolveDependency -Tasks build" first.'
}
}

BeforeAll {
$script:dscModuleName = 'SqlServerDsc'

$env:SqlServerDscCI = $true

Import-Module -Name $script:dscModuleName

# Loading mocked classes
Add-Type -Path (Join-Path -Path (Join-Path -Path $PSScriptRoot -ChildPath '../Stubs') -ChildPath 'SMO.cs')

$PSDefaultParameterValues['InModuleScope:ModuleName'] = $script:dscModuleName
$PSDefaultParameterValues['Mock:ModuleName'] = $script:dscModuleName
$PSDefaultParameterValues['Should:ModuleName'] = $script:dscModuleName
}

AfterAll {
$PSDefaultParameterValues.Remove('InModuleScope:ModuleName')
$PSDefaultParameterValues.Remove('Mock:ModuleName')
$PSDefaultParameterValues.Remove('Should:ModuleName')

# Unload the module being tested so that it doesn't impact any other tests.
Get-Module -Name $script:dscModuleName -All | Remove-Module -Force

Remove-Item -Path 'env:SqlServerDscCI'
}

Describe 'Get-SqlDscServerProtocol' -Tag 'Public' {
Context 'When getting server protocol information' {
BeforeAll {
# Mock the Get-SqlDscManagedComputer command
Mock -CommandName Get-SqlDscManagedComputer -MockWith {
$mockServerInstance = [PSCustomObject]@{
ServerProtocols = @{
'Tcp' = [PSCustomObject]@{
Name = 'Tcp'
DisplayName = 'TCP/IP'
IsEnabled = $true
ProtocolProperties = @{
ListenOnAllIPs = $true
KeepAlive = 30000
}
}
'Np' = [PSCustomObject]@{
Name = 'Np'
DisplayName = 'Named Pipes'
IsEnabled = $false
}
'Sm' = [PSCustomObject]@{
Name = 'Sm'
DisplayName = 'Shared Memory'
IsEnabled = $true
}
}
}

return [PSCustomObject]@{
ServerInstances = @{
'MSSQLSERVER' = $mockServerInstance
'SQL2019' = $mockServerInstance
}
}
}

# Mock Get-ProtocolNameProperties since it's from SqlServerDsc.Common
Mock -CommandName Get-ProtocolNameProperties -MockWith {
param($ProtocolName)

switch ($ProtocolName)
{
'TcpIp' { return @{ Name = 'Tcp'; DisplayName = 'TCP/IP' } }
'NamedPipes' { return @{ Name = 'Np'; DisplayName = 'Named Pipes' } }
'SharedMemory' { return @{ Name = 'Sm'; DisplayName = 'Shared Memory' } }
}
}
}

It 'Should return TcpIp protocol information' {
$result = Get-SqlDscServerProtocol -InstanceName 'MSSQLSERVER' -ProtocolName 'TcpIp'

$result | Should -Not -BeNullOrEmpty
$result.Name | Should -Be 'Tcp'
$result.DisplayName | Should -Be 'TCP/IP'
$result.IsEnabled | Should -Be $true

Should -Invoke -CommandName Get-SqlDscManagedComputer -Exactly -Times 1 -Scope It
Should -Invoke -CommandName Get-ProtocolNameProperties -ParameterFilter {
$ProtocolName -eq 'TcpIp'
} -Exactly -Times 1 -Scope It
}

It 'Should return NamedPipes protocol information' {
$result = Get-SqlDscServerProtocol -InstanceName 'MSSQLSERVER' -ProtocolName 'NamedPipes'

$result | Should -Not -BeNullOrEmpty
$result.Name | Should -Be 'Np'
$result.DisplayName | Should -Be 'Named Pipes'
$result.IsEnabled | Should -Be $false

Should -Invoke -CommandName Get-SqlDscManagedComputer -Exactly -Times 1 -Scope It
Should -Invoke -CommandName Get-ProtocolNameProperties -ParameterFilter {
$ProtocolName -eq 'NamedPipes'
} -Exactly -Times 1 -Scope It
}

It 'Should return SharedMemory protocol information' {
$result = Get-SqlDscServerProtocol -InstanceName 'MSSQLSERVER' -ProtocolName 'SharedMemory'

$result | Should -Not -BeNullOrEmpty
$result.Name | Should -Be 'Sm'
$result.DisplayName | Should -Be 'Shared Memory'
$result.IsEnabled | Should -Be $true

Should -Invoke -CommandName Get-SqlDscManagedComputer -Exactly -Times 1 -Scope It
Should -Invoke -CommandName Get-ProtocolNameProperties -ParameterFilter {
$ProtocolName -eq 'SharedMemory'
} -Exactly -Times 1 -Scope It
}

It 'Should use specified server name' {
$result = Get-SqlDscServerProtocol -ServerName 'TestServer' -InstanceName 'MSSQLSERVER' -ProtocolName 'TcpIp'

Should -Invoke -CommandName Get-SqlDscManagedComputer -ParameterFilter {
$ServerName -eq 'TestServer'
} -Exactly -Times 1 -Scope It
}

It 'Should work with named instances' {
$result = Get-SqlDscServerProtocol -InstanceName 'SQL2019' -ProtocolName 'TcpIp'

$result | Should -Not -BeNullOrEmpty
$result.Name | Should -Be 'Tcp'
}
}

Context 'When the SQL Server instance is not found' {
BeforeAll {
Mock -CommandName Get-SqlDscManagedComputer -MockWith {
return [PSCustomObject]@{
ServerInstances = @{
'MSSQLSERVER' = [PSCustomObject]@{
ServerProtocols = @{}
}
}
}
}

Mock -CommandName Get-ProtocolNameProperties -MockWith {
return @{ Name = 'Tcp'; DisplayName = 'TCP/IP' }
}
}

It 'Should throw an error when instance is not found' {
{ Get-SqlDscServerProtocol -InstanceName 'NONEXISTENT' -ProtocolName 'TcpIp' } | Should -Throw '*Could not find SQL Server instance*'
}
}

Context 'When the protocol is not found' {
BeforeAll {
Mock -CommandName Get-SqlDscManagedComputer -MockWith {
$mockServerInstance = [PSCustomObject]@{
ServerProtocols = @{
# Missing the Tcp protocol
}
}

return [PSCustomObject]@{
ServerInstances = @{
'MSSQLSERVER' = $mockServerInstance
}
}
}

Mock -CommandName Get-ProtocolNameProperties -MockWith {
return @{ Name = 'Tcp'; DisplayName = 'TCP/IP' }
}
}

It 'Should throw an error when protocol is not found' {
{ Get-SqlDscServerProtocol -InstanceName 'MSSQLSERVER' -ProtocolName 'TcpIp' } | Should -Throw '*Could not find server protocol*'
}
}

Context 'When testing parameter sets' {
It 'Should have the correct parameters in parameter set __AllParameterSets' -ForEach @(
@{
ExpectedParameterSetName = '__AllParameterSets'
ExpectedParameters = '[[-ServerName] <string>] [-InstanceName] <string> [-ProtocolName] <string> [<CommonParameters>]'
}
) {
$result = (Get-Command -Name 'Get-SqlDscServerProtocol').ParameterSets |
Where-Object -FilterScript { $_.Name -eq $ExpectedParameterSetName } |
Select-Object -Property @(
@{ Name = 'ParameterSetName'; Expression = { $_.Name } },
@{ Name = 'ParameterListAsString'; Expression = { $_.ToString() } }
)
$result.ParameterSetName | Should -Be $ExpectedParameterSetName
$result.ParameterListAsString | Should -Be $ExpectedParameters
}

It 'Should have InstanceName as a mandatory parameter' {
$parameterInfo = (Get-Command -Name 'Get-SqlDscServerProtocol').Parameters['InstanceName']
$parameterInfo.Attributes.Mandatory | Should -BeTrue
}

It 'Should have ProtocolName as a mandatory parameter' {
$parameterInfo = (Get-Command -Name 'Get-SqlDscServerProtocol').Parameters['ProtocolName']
$parameterInfo.Attributes.Mandatory | Should -BeTrue
}

It 'Should have ServerName as an optional parameter' {
$parameterInfo = (Get-Command -Name 'Get-SqlDscServerProtocol').Parameters['ServerName']
$parameterInfo.Attributes.Mandatory | Should -BeFalse
}
}
}
Loading