1

I'm working on a project that pulls a list of SQL instances from server A and then loops through the returned list and runs a query (eventually to audit users and insert results into table) but getting an error instance not found. It seems I'm not defining the variable correctly in the loop because if I hardcode the instance name it works.

I appreciate any input on how to fix this.

$Serverlist = invoke-sqlcmd -ServerInstance TESTSERVER1 -Database TESTDB -Query "SELECT instancename from testtable"

foreach ($SQLInst in $Serverlist) 
{
$Inst = $SQLInst.INSTANCE
Invoke-Sqlcmd -ServerInstance ${$Inst} -Database Master -Query "select @@servername as servername" | select -ExpandProperty servername
} #end foreach loop

Invoke-Sqlcmd : A network-related or instance-specific error occurred while establishing a connection to SQL Server. The server was not found or was not accessible. Verify that the instance name is correct and that SQL Server is configured to allow remote connections. (provider: Named Pipes Provider, error: 40 - Could not open a connection to SQL Server) At line:12 char:1 + Invoke-Sqlcmd -ServerInstance ${$SQLInst} -Database Master -Query "select @@serv ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [Invoke-Sqlcmd], SqlException + FullyQualifiedErrorId : SqlExectionError,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand

3 Answers 3

0

There's no reason to use curly braces like that ${$Inst} in this instance.

Simply using $Inst will work fine. If you do use curly braces, then you don't use the $ inside: ${Inst}.

Invoke-Sqlcmd -ServerInstance $Inst

# or

Invoke-Sqlcmd -ServerInstance ${Inst}
Sign up to request clarification or add additional context in comments.

5 Comments

I've tried using both variations and still get the error: Invoke-Sqlcmd : A network-related or instance-specific error occurred while establishing a connection to SQL Server. If I hardcode the instance name that the top query returns it works.
Are you certain that the variable $Inst contains the value you think it does? Add a Write-Verbose -Message "~$Inst~" -Verbose and see what it says, or better yet debug the code and add a breakpoint so you can inspect the variables.
I don't get any output with the statement but if I add Write-Output $SQLInst I get a value. Am I qualifying $Inst as an instance name correctly?
@JeffA you're defining $Inst = $SQLInst.INSTANCE ; does $SQLInst actually contain a property called INSTANCE?
I think I have it, you pointed me in the right direction thanks!
0

I would check to make sure that each instance is the correct one:

$Serverlist = invoke-sqlcmd -ServerInstance TESTSERVER1 -Database TESTDB -Query "SELECT instancename from testtable"

    foreach ($SQLInst in $Serverlist) 
    {
      $Inst = $SQLInst.INSTANCE
      Write-Host $Inst
    } #end foreach loop

I noticed some problems with my previous statement. Can you try this?

$Serverlist = invoke-sqlcmd -ServerInstance TESTSERVER1 -Database TESTDB -Query "SELECT instancename from testtable"

foreach ($SQLInst in $Serverlist) 
{  
  $Inst = $SQLInst.instancename
Invoke-Sqlcmd -ServerInstance "$Inst" -Database Master -Query "select @@servername as servername" | select -ExpandProperty servername
} #end foreach loop

7 Comments

I'm getting an error when I make that change: Invoke-Sqlcmd : Value cannot be null. Parameter name: ServerInstance At line:16 char:1 + Invoke-Sqlcmd -ServerInstance $SQLInst -Database Master -Query "select @@servern ... + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidArgument: (:) [Invoke-Sqlcmd], ArgumentNullException + FullyQualifiedErrorId : CannotGetServerInstance,Microsoft.SqlServer.Management.PowerShell.GetScriptCommand
Check if $Serverlist array is populated. You can do output the values into shell: Write-Host $Serverlist
I added that and get the output "System.Data.DataRow" currently I have the query only returning one value for testing.
What version of powershell are you using? You can find out by typing $PSVersionTable into PowerShell concole.
Appears to be PSVersion 4.0
|
0

When you are referencing a result from a query, you must specify the column name even if there is only one column in the query. Enclosing the query in parentheses and using dot notation with the column name will convert the rows to a list of values. Your original problem was you had the column name incorrect.

Try this:

$Serverlist = ( invoke-sqlcmd -ServerInstance TESTSERVER1 -Database TESTDB -Query "SELECT instancename from testtable").instancename

$Serverlist | ForEach-Object {
    ( Invoke-Sqlcmd -ServerInstance $SQLInst -Database Master -Query 'select @@servername as servername' ).servername
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.