sql-serverpowershellinvoke-sqlcmd

Powershell invoke-sqlcmd Printing The Wrong Output


I have a SQL query that is running as expected however when I try to use it in PowerShell 'Invoke-SqlCmd' module, the output comes out different than when querying the database. I noticed that there are quite a few questions regarding this module but I couldn't find one that is applicable to my case.

Query:

    $SQLServer = "localhost"
    $query = "SELECT Groups.[Name] AS AGname FROM sys.dm_hadr_availability_group_states States INNER JOIN master.sys.availability_groups Groups ON States.group_id = Groups.group_id WHERE primary_replica = @@Servername"

    $HAGName = Invoke-Sqlcmd  -query $query -ServerInstance $SQLServer -Database 'database' 

    if ($HAGName = !$null) {
        
        write-host "Availability group name is $HAGName"
        exit 0
    }
    else {

        write-host "Failed to retrieve High Availability group name = [$HAGName]"
        exit 1
    }

Output in PowerShell: 'Availability group name is True'

Like I mentioned, when querying SQL Server directly I get the correct output. I tried using the 'OutputAs' switch but it didn't help.

Any help will be greatly appreciated.


Solution

  • All the pointers are in the comments on the question, but let me break it down systematically:

    Therefore, $null -eq $HAGName is what you meant to use (placing the $null on the LHS, for robustness - see the docs).

    However, given PowerShell's implicit to-Boolean coercion rules (see the bottom section of this answer), you could simplify to if ($HAGName) { ... } in this case.

    Therefore, a more PowerShell-idiomatic reformulation of your code is:

    $SQLServer = 'localhost'
    $query = 'SELECT Groups.[Name] AS AGname FROM sys.dm_hadr_availability_group_states States INNER JOIN master.sys.availability_groups Groups ON States.group_id = Groups.group_id WHERE primary_replica = @@Servername'
    
    $HAGName = Invoke-Sqlcmd -Query $query -ServerInstance $SQLServer -Database database
    
    if ($HAGName) {
        Write-Verbose -Verbose "Availability group name is: "
        # Output the System.Data.DataRow instance as-is,
        # which also results in proper for-display formatting.
        # If you just want the value of the .AGname property (column), use
        #  $HAGName.AGname instead.
        $HAGName 
        exit 0
    }
    else {
        Write-Warning "Failed to retrieve High Availability group name."
        exit 1
    }
    

    Note: