patternsqlMinor
How does the PowerShell SQLPS SQLSERVER provider detect central management servers in SQLRegistration\Central Management Server Group
Viewed 0 times
theprovidergroupserverscentralsqlserverpowershellsqlregistrationserverdoes
Problem
I'm experiencing odd behavior with the PowerShell SQLSERVER provider and the SQLRegistration\Central Management Server Group directory. Below are the behaviors. I would like to know how the SQLSERVER provider knows what CMS's are registered so that I can understand why it doesn't seem to notice the registration when done in SSMS 2014 (see below for detailed behavior). Also, why my connection fails when I know the instance is online.
Setup
Machine
Instances
Behavior 1
Using SSMS 2014, I registered localhost\SQL2012 as a CMS. Executing this code returns no items.
Open and closing the PowerShell console and SSMS does not change the results. If I open SSMS 2012 and register localhost\SQL2012 as a CMS and re-run the above command, I see localhost\SQL2012 registered as expected.
Behavior 2
After getting the server to list successfully...
Directory: Microsoft.SqlServer.Management.PSProvider\SqlServer::SQLSERVER:\SQLRegistration\Central Management
Server Group
Mode Name
And running the below command to try and navigate to my registered server groups fails with the below error, even though the instance is online and available.
Set-Location : Cannot find path 'SQLSERVER:\SQLRegistration\Central Management Server Group\localhost\SQL2012\'
because it does not exist.
At line:1 char:1
+ Set-Location "localhost\SQL2012\"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (SQLSERVER:\SQLR...alhost\SQL2012:String) [Set-Location], ItemNotFoundE
xception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
Update 1
SMO seems to work fine. The below code successful
Setup
Machine
- localhost
Instances
- localhost\SQL2012
- localhost\SQL2014
- localhost\SQL2014_1
Behavior 1
Using SSMS 2014, I registered localhost\SQL2012 as a CMS. Executing this code returns no items.
PS SQLSERVER:\SQLRegistration\Central Management Server Group> dirOpen and closing the PowerShell console and SSMS does not change the results. If I open SSMS 2012 and register localhost\SQL2012 as a CMS and re-run the above command, I see localhost\SQL2012 registered as expected.
Behavior 2
After getting the server to list successfully...
Directory: Microsoft.SqlServer.Management.PSProvider\SqlServer::SQLSERVER:\SQLRegistration\Central Management
Server Group
Mode Name
- localhost\SQL2012
And running the below command to try and navigate to my registered server groups fails with the below error, even though the instance is online and available.
PS SQLSERVER:\SQLRegistration\Central Management Server Group> Set-Location "localhost\SQL2012\"Set-Location : Cannot find path 'SQLSERVER:\SQLRegistration\Central Management Server Group\localhost\SQL2012\'
because it does not exist.
At line:1 char:1
+ Set-Location "localhost\SQL2012\"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (SQLSERVER:\SQLR...alhost\SQL2012:String) [Set-Location], ItemNotFoundE
xception
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.SetLocationCommand
Update 1
SMO seems to work fine. The below code successful
Solution
Shawn's explanation about discrepancies between SQL Server version seems on target. For this reason, I believe the SMO is a more stable method. I'm going forward using the below code.
Import-Module SQLPS -DisableNameChecking
Function Parse-ServerGroup($serverGroup)
{
$results = $serverGroup.RegisteredServers;
foreach($group in $serverGroup.ServerGroups)
{
$results += Parse-ServerGroup -serverGroup $group;
}
return $results;
}
Function Get-ServerList ([string]$cmsName, [string]$serverGroup, [switch]$recurse)
{
$connectionString = "data source=$cmsName;initial catalog=master;integrated security=sspi;"
$sqlConnection = New-Object ("System.Data.SqlClient.SqlConnection") $connectionstring
$conn = New-Object ("Microsoft.SQLServer.Management.common.serverconnection") $sqlconnection
$cmsStore = New-Object Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore($conn)
$cmsRootGroup = $cmsStore.ServerGroups["DatabaseEngineServerGroup"].ServerGroups[$serverGroup]
if($recurse)
{
return Parse-ServerGroup -serverGroup $cmsRootGroup | select ServerName
}
else
{
return $cmsRootGroup.RegisteredServers | select ServerName
}
}
Get-ServerList -cmsName "localhost\SQL2012" -serverGroup "Production" -recurse | Format-TableCode Snippets
Import-Module SQLPS -DisableNameChecking
Function Parse-ServerGroup($serverGroup)
{
$results = $serverGroup.RegisteredServers;
foreach($group in $serverGroup.ServerGroups)
{
$results += Parse-ServerGroup -serverGroup $group;
}
return $results;
}
Function Get-ServerList ([string]$cmsName, [string]$serverGroup, [switch]$recurse)
{
$connectionString = "data source=$cmsName;initial catalog=master;integrated security=sspi;"
$sqlConnection = New-Object ("System.Data.SqlClient.SqlConnection") $connectionstring
$conn = New-Object ("Microsoft.SQLServer.Management.common.serverconnection") $sqlconnection
$cmsStore = New-Object Microsoft.SqlServer.Management.RegisteredServers.RegisteredServersStore($conn)
$cmsRootGroup = $cmsStore.ServerGroups["DatabaseEngineServerGroup"].ServerGroups[$serverGroup]
if($recurse)
{
return Parse-ServerGroup -serverGroup $cmsRootGroup | select ServerName
}
else
{
return $cmsRootGroup.RegisteredServers | select ServerName
}
}
Get-ServerList -cmsName "localhost\SQL2012" -serverGroup "Production" -recurse | Format-TableContext
StackExchange Database Administrators Q#77872, answer score: 2
Revisions (0)
No revisions yet.