powershellinvoke-sqlcmd

Invoke-Sqlcmd Join variable as table


Is there a way to link a PS variable as a table within the Invoke-Sqlcmd? I've tried LEFT JOIN $psvar as p on T1.ID=P.ID

I updated the script by making a DataTable from the advice of @Cpt.Whale.

# Define DataTable Columns
$tbl = New-Object system.Data.DataTable 'tbl_New'
$newcol = New-Object system.Data.DataColumn emplID,([string]); $tbl.columns.add($newcol)
$newcol = New-Object system.Data.DataColumn adGrp,([string]); $tbl.columns.add($newcol)

# Add data from Excel
$exelWkbk = '.\table.xlsx'
$excelQuery = '
        SELECT  F1 as emplID
                ,F2 as pcType
        FROM    [Sheet1$]
'
$queryOutput = Invoke-ExcelQuery $exelWkbk $excelQuery | Select-Object -Skip 1

$queryOutput | ForEach-Object {
    $row = $tbl.NewRow()
    $row.tmplID = ($_.emplID)
    $row.adGrp = ($_.pcType)
    $tbl.Rows.Add($row)
}

# Query SQL Data source joining Excel data
$sqlQuery = "
        USE SQLDATABASE;
        DECLARE @today as date = GETDATE();
        SELECT  emp.USER_ID
                ,wt.HOST
                ,a.pcType as DevicModel
        FROM    workstationTable as wt
                JOIN employeeTable as emp on wt.USER_ID = emp.USER_ID
                JOIN $tbl as a on emp.USER_ID = a.emplID
        WHERE   emp.NAME is not NULL
"
Invoke-Sqlcmd -Query $sqlQuery -ServerInstance 'dbName' |
Out-GridView

Solution

  • Powershell doesn't have a built-in function for doing SQL-style joins of different datasets. You can use Select-Object calculated properties for simple lookup-table type things, but I prefer using the Join-Object module built on LINQ:

    # Gather both data sources into separate list variables:
    $sqlData = Invoke-Sqlcmd -ServerInstance 'dbName' -Query '
      USE SQLDATABASE;
        DECLARE @today as date = GETDATE();
        SELECT  emp.USER_ID,wt.HOST
        FROM    workstationTable as wt
          JOIN  employeeTable as emp on wt.USER_ID = emp.USER_ID
        WHERE   emp.NAME is not NULL'
    $excelData = Invoke-ExcelQuery $exelWkbk $excelQuery | Select-Object -Skip 1
    
    # join the lists on a specific property
    $joined = Join-Object -Type AllInLeft `
        -Left $sqlData    -LeftJoinProperty  USER_ID `
        -Right $excelData -RightJoinProperty EmplID 
    
    $joined | Out-GridView
    

    Or since you're already using Excel, an SQL data connection in the file may be an option.