1

My company sells/supports a product that utilizes a SQL database. I've been trying to create a PowerShell script to prep the entire server for a new install. The script needs to install all the required Windows Server Roles/features, then install SQL, then SQL Server Management Studio, and finally, Enable TCP/IP for SQL. I have gotten all but the last step to work, and trying to figure this one out is kicking my butt...

I feel like I'm on the right path here, but I'm currently stuck...

If I run:

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

I actually get results showing:

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

I'm then using this information and running:

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

With this, I get the following error:

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

Anybody have any idea what I'm doing wrong? I feel like, if I can figure this part out, I can figure out how to alter the settings, but I can't even pull up the settings at this point.

Christopher Cass
  • 817
  • 4
  • 19
  • 31

1 Answers1

4

You should consider looking at dbatools, a PowerShell module written by SQL Server and PowerShell MVPs with hundreds of really useful functions for managing SQL Server.

I thought they might have a function that does what you need already. It looks like they don't, but in searching I had a look at Set-DbaTcpPort, and finally at the source code for that function on GitHub, where I saw this code snippet:

$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' }

So that led me to conclude that you could do the same with your object; your $wmi object seems to be the same as their $wmiinstance object even if you arrived at them slightly differently.

From there you can query with Where-Object or the .Where method:

$tcp = $wmi.ClientProtocols.Where({$_.DisplayName -eq 'TCP/IP'})
briantist
  • 45,546
  • 6
  • 82
  • 127