使用 PowerShell 在 SQL 服务器配置管理器中启用 TCP/IP

Use PowerShell To Enable TCP/IP in SQL Server Configuration Manager

我的公司 sells/supports 一个使用 SQL 数据库的产品。我一直在尝试创建一个 PowerShell 脚本来为整个服务器准备新安装。该脚本需要安装所有必需的 Windows Server Roles/features,然后安装 SQL,然后是 SQL Server Management Studio,最后,为 [= 启用 TCP/IP 34=]。除了最后一步,我已经完成了所有工作,而试图弄清楚这一点是在踢我的屁股...

我觉得我走在正确的道路上,但我目前被困住了...

如果我运行:

$smo = 'Microsoft.SqlServer.Management.Smo.'
$wmi = new-object ($smo + 'Wmi.ManagedComputer')
$wmi

我实际得到的结果显示:

ConnectionSettings : 
Microsoft.SqlServer.Management.Smo.Wmi.WmiConnectionInfo
Services           : {MSSQL$WEBACCESS, MSSQLFDLauncher$WEBACCESS, 
SQLAgent$WEBACCESS, SQLBrowser}
ClientProtocols    : {np, sm, tcp}
ServerInstances    : {SQLSERVER}
ServerAliases      : {}
Urn                : ManagedComputer[@Name='HOSTNAME']
Name               : HOSTNAME
Properties         : {}
UserData           : 
State              : Existing

然后我将使用此信息和 运行ning:

$uri = "ManagedComputer[@Name='']/ ServerInstance[@Name='']/ServerProtocol[@Name='Tcp']"
$Tcp = $wmi.GetSmoObject($uri)
$Tcp

有了这个,我得到以下错误:

Exception calling "GetSmoObject" with "1" argument(s): "Attempt to retrieve data for object failed for ManagedComputer 'HOSTNAME'."
At line:9 char:1
+ $Tcp = $wmi.GetSmoObject($uri)
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], 
ParentContainsErrorRecordException
    + FullyQualifiedErrorId : FailedOperationException

有人知道我做错了什么吗?我觉得,如果我能弄清楚这部分,我就能弄清楚如何更改设置,但此时我什至无法调出设置。

您应该考虑查看 dbatools,这是一个由 SQL 服务器和 PowerShell MVP 编写的 PowerShell 模块,其中包含数百个非常有用的功能,用于管理 SQL 服务器。

我认为他们可能已经具备满足您需要的功能。看起来他们没有,但在搜索时我查看了 Set-DbaTcpPort, and finally at the source code for that function on GitHub,在那里我看到了这个代码片段:

$wmi = New-Object Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $instance
$wmiinstance = $wmi.ServerInstances | Where-Object { $_.Name -eq $wmiinstancename }
$tcp = $wmiinstance.ServerProtocols | Where-Object { $_.DisplayName -eq 'TCP/IP' }
$IpAddress = $tcp.IpAddresses | where-object { $_.IpAddress -eq $IpAddress }
$tcpport = $IpAddress.IpAddressProperties | Where-Object { $_.Name -eq 'TcpPort' }

所以这让我得出结论,你可以对你的对象做同样的事情;你的 $wmi 对象似乎与他们的 $wmiinstance 对象相同,即使你得到的对象略有不同。

从那里您可以使用 Where-Object.Where 方法查询:

$tcp = $wmi.ClientProtocols.Where({$_.DisplayName -eq 'TCP/IP'})