Select-Sql.ps1
function Select-SQL { <# .Synopsis Select SQL data .Description Select data from a SQL databsae .Example Select-Sql -FromTable ATable -Property Name, Day, Month, Year -Where "Year = 2005" -ConnectionSetting SqlAzureConnectionString .Example Select-Sql -FromTable INFORMATION_SCHEMA.TABLES -ConnectionSetting SqlAzureConnectionString -Property Table_Name -verbose .Example Select-Sql -FromTable INFORMATION_SCHEMA.TABLES -ConnectionSetting "Data Source=$env:ComputerName;Initial Catalog=Master;Integrated Security=SSPI;" -Property Table_Name -verbose .Example Select-Sql " SELECT sys.objects.name, SUM(row_count) AS 'Row Count', SUM(reserved_page_count) * 8.0 / 1024 AS 'Table Size (MB)' FROM sys.dm_db_partition_stats, sys.objects WHERE sys.dm_db_partition_stats.object_id = sys.objects.object_id GROUP BY sys.objects.name ORDER BY [Table Size (MB)] DESC " .Link Add-SqlTable .Link Update-SQL #> [CmdletBinding(DefaultParameterSetName='SQLQuery')] [OutputType([PSObject], [Hashtable], [Data.DataRow])] param( # The table containing SQL results [Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true,ParameterSetName='SQLQuery')] [Alias('SQL')] [string]$Query, # The path to a SQL file [Parameter(Mandatory=$true,ValueFromPipelineByPropertyName=$true,ParameterSetName='SQLFile')] [Alias('Fullname')] [string]$SqlFile, # The table containing SQL results [Parameter(Mandatory=$true,Position=0,ValueFromPipelineByPropertyName=$true,ParameterSetName='SimpleSQL')] [Alias('Table','From', 'TableName')] [string]$FromTable, # If set, will only return unique values. This corresponds to the DISTINCT SQL qualifier. [Parameter(ValueFromPipelineByPropertyName=$true,ParameterSetName='SimpleSQL')] [Alias('Unique')] [Switch]$Distinct, # The properties to pull from SQL. If not set, all properties (*) will be returned [Parameter(ValueFromPipelineByPropertyName=$true,ParameterSetName='SimpleSQL')] [string[]]$Property, # The sort order of the returned objects [Parameter(ValueFromPipelineByPropertyName=$true,ParameterSetName='SimpleSQL')] [Alias('First')] [Uint32]$Top, # The sort order of the returned objects [Parameter(ValueFromPipelineByPropertyName=$true,ParameterSetName='SimpleSQL')] [Alias('Sort')] [string[]]$OrderBy, # If set, sorted items will be returned in descending order. By default, if items are sorted, they will be in ascending order. [Parameter(ValueFromPipelineByPropertyName=$true,ParameterSetName='SimpleSQL')] [Switch]$Descending, # The where clause. [Parameter(ValueFromPipelineByPropertyName=$true,ParameterSetName='SimpleSQL')] [string]$Where, # A connection string or setting. [Alias('ConnectionString', 'ConnectionSetting')] [string]$ConnectionStringOrSetting, # The name of the SQL server. This is used with a database name to craft a connection string to SQL server [string] $Server, # The database on a SQL server. This is used with the server name to craft a connection string to SQL server [string] $Database, # If set, will output the SQL [Switch] $OutputSql, # If set, will use SQL server compact edition [Switch] $UseSQLCompact, # The path to SQL Compact. If not provided, SQL compact will be loaded from the GAC [string] $SqlCompactPath, # If set, will use SQL lite [Alias('UseSqlLite')] [switch] $UseSQLite, # The path to SQLite. If not provided, SQLite will be loaded from Program Files [Alias('SqlLitePath')] [string] $SqlitePath, # If set, will use MySql to connect to the database [Switch] $UseMySql, # The path to MySql's .NET connector. If not provided, MySql will be loaded from Program Files [string] $MySqlPath, # The path to a SQL compact or SQL lite database [Alias('DBPath')] [string] $DatabasePath, # The way the data will be outputted. [ValidateSet("Hashtable", "Datatable", "DataSet", "PSObject")] [string] $AsA = "PSObject", # If set, the select statement will be run as a dirty read. # In SQL Server, this will be With (nolock). # In MYSql, this will change the session options for the transaction to enable a dirty read. [Switch] $Dirty ) begin { if ($PSBoundParameters.ConnectionStringOrSetting) { if ($ConnectionStringOrSetting -notlike "*;*") { $ConnectionString = Get-SecureSetting -Name $ConnectionStringOrSetting -ValueOnly } else { $ConnectionString = $ConnectionStringOrSetting } $script:CachedConnectionString = $ConnectionString } elseif ($psBoundParameters.Server -and $psBoundParameters.Database) { $ConnectionString = "Server=$Server;Database=$Database;Integrated Security=True;" $script:CachedConnectionString = $ConnectionString } elseif ($script:CachedConnectionString){ $ConnectionString = $script:CachedConnectionString } else { $ConnectionString = "" } if (-not $ConnectionString -and -not ($UseSQLite -or $UseSQLCompact)) { throw "No Connection String" return } if (-not $OutputSQL) { if ($UseSQLCompact) { if (-not ('Data.SqlServerCE.SqlCeConnection' -as [type])) { if ($SqlCompactPath) { $resolvedCompactPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($SqlCompactPath) $asm = [reflection.assembly]::LoadFrom($resolvedCompactPath) } else { $asm = [reflection.assembly]::LoadWithPartialName("System.Data.SqlServerCe") } $null = $asm } $resolvedDatabasePath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($DatabasePath) $sqlConnection = New-Object Data.SqlServerCE.SqlCeConnection "Data Source=$resolvedDatabasePath" $sqlConnection.Open() } elseif ($UseSqlite) { if (-not ('Data.Sqlite.SqliteConnection' -as [type])) { if ($sqlitePath) { $resolvedLitePath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($sqlitePath) $asm = [reflection.assembly]::LoadFrom($resolvedLitePath) } else { $asm = [Reflection.Assembly]::LoadFrom("$env:ProgramFiles\System.Data.SQLite\2010\bin\System.Data.SQLite.dll") } $null = $asm } $resolvedDbPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($DatabasePath) $sqlConnection = New-Object Data.Sqlite.SqliteConnection "Data Source=$resolvedDbPath" $sqlConnection.Open() } elseif ($useMySql) { if (-not ('MySql.Data.MySqlClient.MySqlConnection' -as [type])) { if (-not $mySqlPath) { $programDir = if (${env:ProgramFiles(x86)}) { ${env:ProgramFiles(x86)} } else { ${env:ProgramFiles} } $mySqlPath = Get-ChildItem "$programDir\MySQL\Connector NET 6.7.4\Assemblies\"| Where-Object { $_.Name -like "*v*" } | Sort-Object { $_.Name.Replace("v", "") -as [Version] } -Descending | Select-object -First 1 | Get-ChildItem -filter "MySql.Data.dll" | Select-Object -ExpandProperty Fullname } $asm = [Reflection.Assembly]::LoadFrom($MySqlPath) $null = $asm } $sqlConnection = New-Object MySql.Data.MySqlClient.MySqlConnection "$ConnectionString" $sqlConnection.Open() } else { $sqlConnection = New-Object Data.SqlClient.SqlConnection "$connectionString" $sqlConnection.Open() } } } process { $dataSet = $null if ($PSCmdlet.ParameterSetName -eq 'SimpleSQL') { if (-not $Property) { $property = "*" } if ($Property -eq '*') { $propString = '*' } else { if ($Property -like "*(*)*") { $propString = "$($Property -join ',')" } else { $propString = "`"$($Property -join '","')`"" } } # Very minor SQL injection prevention. If this is your last line of defense, you're in trouble, but using this will keep you out of some trouble. if ($where.IndexOfAny(";$([Environment]::NewLine)`0`b`t".ToCharArray()) -ne -1) { Write-Error "The Where Statement doesn't look safe" return } $sqlStatement = "SELECT $(if ($Top) { "TOP $Top" } ) $(if ($Distinct) { 'DISTINCT ' }) $propString FROM $FromTable $(if ($Where) { "WHERE $where"}) $(if ($OrderBy) { "ORDER BY $($orderBy -join ',') $(if ($Descending) { 'DESC'})"})".TrimEnd("\").TrimEnd("/") Write-Verbose "$sqlStatement" } elseif ($PSCmdlet.ParameterSetName -eq 'SQLQuery') { $sqlStatement = $Query } elseif ($PSCmdlet.ParameterSetName -eq 'SQLFile') { $resolvedPath = $ExecutionContext.SessionState.Path.GetResolvedPSPathFromPSPath($SqlFile) if (-not $resolvedPath) { return } $sqlStatement = [IO.File]::ReadAllText("$resolvedPath") } if ($Dirty) { if ($UseMySql) { $sqlStatement = " SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ; $sqlStatement ; SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ ; " } elseif (-not ($UseSQLCompact -or $UseSQLite)) { $sqlStatement += " WITH (nolock)" } } $dataset = $null if ($OutputSql) { $sqlStatement } else { if ($UseSQLCompact) { $sqlAdapter= New-Object "Data.SqlServerCE.SqlCeDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } elseif ($UseSQLite) { $sqlAdapter= New-Object "Data.SQLite.SQLiteDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } elseif ($UseMySql) { $sqlAdapter= New-Object "MySql.Data.MySqlClient.MySqlDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } else { $sqlAdapter= New-Object "Data.SqlClient.SqlDataAdapter" ($sqlStatement, $sqlConnection) $sqlAdapter.SelectCommand.CommandTimeout = 0 $dataSet = New-Object Data.DataSet $rowCount = $sqlAdapter.Fill($dataSet) } } if ($dataSet) { if ($AsA -eq 'DataSet') { $dataSet } elseif ($AsA -eq 'DataTable') { foreach ($t in $dataSet.Tables) { ,$t } } elseif ($AsA -eq 'PSObject') { foreach ($t in $dataSet.Tables) { foreach ($r in $t.Rows) { if ($r.pstypename) { $r.pstypenames.clear() foreach ($tn in ($r.pstypename -split "\|")) { if ($tn) { $r.pstypenames.add($tn) } } } $null = $r.psobject.properties.Remove("pstypename") $r } } } elseif ($AsA -eq 'Hashtable') { $avoidProperties = @{} foreach ($pName in 'RowError', 'RowState', 'Table', 'ItemArray', 'HasErrors') { $avoidProperties[$pName] = $true } foreach ($t in $dataSet.Tables) { foreach ($r in $t.Rows) { $out = @{} foreach ($prop in $r.psobject.Properties) { if ($avoidProperties[$prop.Name]) { continue } $out[$prop.Name] = $prop.Value } $out } } } } } end { if ($sqlConnection) { $sqlConnection.Close() $sqlConnection.Dispose() } } } |