SQLExtensions.psm1
function Invoke-SQLQuery { [CmdletBinding()] [OutputType([System.Data.DataTable])] param ( #SqlConnection [Parameter(Mandatory=$true)] [System.Data.SqlClient.SqlConnection]$SqlConnection, #Query [Parameter(Mandatory=$true)] [string]$Query, #TimeoutInSeconds [Parameter(Mandatory=$false)] [int]$TimeoutInSeconds = 60 ) Process { #Execute Query try { Write-Verbose "Execute Query started" $Command = $SqlConnection.CreateCommand() $Command.CommandText = $Query $Command.CommandTimeout = $TimeoutInSeconds $SqlResult = $Command.ExecuteReader() if ($SqlResult) { $result = New-Object -TypeName System.Data.DataTable $result.Load($SqlResult) if ($result) { $result } } Write-Verbose "Execute Query completed" } catch { Write-Error "Execute Query failed. Details: $_" -ErrorAction 'Stop' } } } function Get-SqlInstalledComponents { [CmdletBinding()] [OutputType([object])] param ( #VersionNumber [Parameter(Mandatory=$true,ParameterSetName='NoRemoting_Default')] [ValidateSet('100','110','120','130')] [string]$VersionNumber, [Parameter(Mandatory=$false,ParameterSetName='NoRemoting_Default')] [string]$InstanceName ) Begin { $RegPropsToExclude = 'PSPath','PSParentPath','PSChildName','PSDrive','PSProvider' $SqlRegLocation = 'HKLM:\SOFTWARE\Microsoft\Microsoft SQL Server' $SqlSharedComponentsRegLocation = "$SqlRegLocation\$VersionNumber\ConfigurationState" $SqlInstanceComponentsRegLocation = "$SqlRegLocation\Instance Names" } Process { $Result = @{ SqlDetected=$false Shared=@() Instances=@{ RS=@() SQL=@() } } $SqlInstalled = Test-Path -Path $SqlRegLocation if ($SqlInstalled) { $Result['SqlDetected'] = $true #Get Shared Components try { $SqlSharedComponentsTemp = Get-ItemProperty -Path $SqlSharedComponentsRegLocation -Name 'SQL_*' -ErrorAction Stop $SqlSharedComponentsTemp = $SqlSharedComponentsTemp.psobject.Properties | Where-Object {($RegPropsToExclude -notcontains $_.Name) -and ($_.Value -eq 1)} | select -ExpandProperty Name $Result['Shared'] += $SqlSharedComponentsTemp if(([int]$VersionNumber) -eq 130) { if((Test-Path -Path "$SqlRegLocation\$VersionNumber\Tools\Setup\SQL_SSMS_Adv") -and ((Get-ItemProperty -Path "$SqlRegLocation\$VersionNumber\Tools\Setup\SQL_SSMS_Adv").FeatureList -like "*SQL_SSMS_Adv=3*")) { $Result['Shared'] += 'SQL_SSMS_Adv' $Result['Shared'] += 'SQL_SSMS_Full' } } if(([int]$VersionNumber) -gt 130) { throw "SSMS check is not implemented yet for versions above 130" } } catch { } #Get RS Instance Components try { $SqlRsInstanceComponentsTemp = Get-ItemProperty -Path "$SqlInstanceComponentsRegLocation\RS" -ErrorAction Stop $SqlRsInstanceComponentsTemp = $SqlRsInstanceComponentsTemp.psobject.Properties | Where-Object {($RegPropsToExclude -notcontains $_.Name)} | foreach { [pscustomobject]@{ Name=$_.Value InstanceName=$_.Name } } if ($PSBoundParameters.ContainsKey('InstanceName')) { $SqlRsInstanceComponentsTemp = $SqlRsInstanceComponentsTemp | Where-Object {$_.InstanceName -eq $InstanceName} } $Result['Instances']['RS'] += $SqlRsInstanceComponentsTemp } catch { } #Get Sql Instance Components try { $SqlSqlInstanceComponentsTemp = Get-ItemProperty -Path "$SqlInstanceComponentsRegLocation\Sql" -ErrorAction Stop $SqlSqlInstanceComponentsTemp = $SqlSqlInstanceComponentsTemp.psobject.Properties | Where-Object {($RegPropsToExclude -notcontains $_.Name)} | foreach { [pscustomobject]@{ Name=$_.Value InstanceName=$_.Name } } if ($PSBoundParameters.ContainsKey('InstanceName')) { $SqlSqlInstanceComponentsTemp = $SqlSqlInstanceComponentsTemp | Where-Object {$_.InstanceName -eq $InstanceName} } $Result['Instances']['Sql'] += $SqlSqlInstanceComponentsTemp } catch { } } #Return Result [pscustomobject]$Result } End { } } function New-SqlConnection { [CmdletBinding()] [OutputType([System.Data.SqlClient.SqlConnection])] param ( #ConnectionString [Parameter(Mandatory=$true)] [string]$ConnectionString, #AccessToken [Parameter(Mandatory=$false)] [string]$AccessToken ) Process { #Create New SqlConnection try { Write-Verbose "Create New SqlConnection started" $connection = New-Object -TypeName System.Data.SqlClient.SqlConnection $connection.ConnectionString = $connectionString if ($PSBoundParameters.ContainsKey('AccessToken')) { $connection.AccessToken = $AccessToken } $connection.Open() $connection Write-Verbose "Create New SqlConnection completed" } catch { Write-Error "Create New SqlConnection failed. Details: $_" -ErrorAction 'Stop' } } } function Test-SqlInstanceNameFormat { [CmdletBinding()] param ( [Parameter(Position=0, Mandatory=$true)] [AllowNull()] [AllowEmptyString()] [string]$SqlInstanceName ) Begin { $SqlReservedKeywords = @('MSSQLServer', 'ADD', 'ALL', 'ALTER', 'AND', 'ANY', 'AS', 'ASC', 'AUTHORIZATION', 'BACKUP', 'BEGIN', 'BETWEEN', 'BREAK', 'BROWSE', 'BULK', 'BY', 'CASCADE', 'CASE', 'CHECK', 'CHECKPOINT', 'CLOSE', 'CLUSTERED', 'COALESCE', 'COLLATE', 'COLUMN', 'COMMIT', 'COMPUTE', 'CONSTRAINT', 'CONTAINS', 'CONTAINSTABLE', 'CONTINUE', 'CONVERT', 'CREATE', 'CROSS', 'CURRENT', 'CURRENT_DATE', 'CURRENT_TIME', 'CURRENT_TIMESTAMP', 'CURRENT_USER', 'CURSOR', 'DATABASE', 'DBCC', 'DEALLOCATE', 'DECLARE', 'DEFAULT', 'DELETE', 'DENY', 'DESC', 'DISK', 'DISTINCT', 'DISTRIBUTED', 'DOUBLE', 'DROP', 'DUMP', 'ELSE', 'END', 'ERRLVL', 'ESCAPE', 'EXCEPT', 'EXEC', 'EXECUTE', 'EXISTS', 'EXIT', 'EXTERNAL', 'FETCH', 'FILE', 'FILLFACTOR', 'FOR', 'FOREIGN', 'FREETEXT', 'FREETEXTTABLE', 'FROM', 'FULL', 'FUNCTION', 'GOTO', 'GRANT', 'GROUP', 'HAVING', 'HOLDLOCK', 'IDENTITY', 'IDENTITY_INSERT', 'IDENTITYCOL', 'IF', 'IN', 'INDEX', 'INNER', 'INSERT', 'INTERSECT', 'INTO', 'IS', 'JOIN', 'KEY', 'KILL', 'LEFT', 'LIKE', 'LINENO', 'LOAD', 'MERGE', 'NATIONAL', 'NOCHECK', 'NONCLUSTERED', 'NOT', 'NULL', 'NULLIF', 'OF', 'OFF', 'OFFSETS', 'ON', 'OPEN', 'OPENDATASOURCE', 'OPENQUERY', 'OPENROWSET', 'OPENXML', 'OPTION', 'OR', 'ORDER', 'OUTER', 'OVER', 'PERCENT', 'PIVOT', 'PLAN', 'PRECISION', 'PRIMARY', 'PRINT', 'PROC', 'PROCEDURE', 'PUBLIC', 'RAISERROR', 'READ', 'READTEXT', 'RECONFIGURE', 'REFERENCES', 'REPLICATION', 'RESTORE', 'RESTRICT', 'RETURN', 'REVERT', 'REVOKE', 'RIGHT', 'ROLLBACK', 'ROWCOUNT', 'ROWGUIDCOL', 'RULE', 'SAVE', 'SCHEMA', 'SECURITYAUDIT', 'SELECT', 'SEMANTICKEYPHRASETABLE', 'SEMANTICSIMILARITYDETAILSTABLE', 'SEMANTICSIMILARITYTABLE', 'SESSION_USER', 'SET', 'SETUSER', 'SHUTDOWN', 'SOME', 'STATISTICS', 'SYSTEM_USER', 'TABLE', 'TABLESAMPLE', 'TEXTSIZE', 'THEN', 'TO', 'TOP', 'TRAN', 'TRANSACTION', 'TRIGGER', 'TRUNCATE', 'TRY_CONVERT', 'TSEQUAL', 'UNION', 'UNIQUE', 'UNPIVOT', 'UPDATE', 'UPDATETEXT', 'USE', 'USER', 'VALUES', 'VARYING', 'VIEW', 'WAITFOR', 'WHEN', 'WHERE', 'WHILE', 'WITH', 'WITHIN GROUP', 'WRITETEXT') $ForbiddenChars = @(' ','\',',',':',';',"'",'&','@','`') } Process { if([string]::IsNullOrWhiteSpace($SqlInstanceName)) { throw "The SQL Instance Name cannot be blank" } if("$SqlInstanceName".Length -gt 16) { throw "The SQL Instance Name must contain 16 characters or less" } if( -not [char]::IsLetter($SqlInstanceName, 0)) { throw "The SQL Instance Name must start with a letter" } if("$SqlInstanceName".Substring("$SqlInstanceName".Length - 1) -eq '_') { throw "The SQL Instance Name cannot end with an underscore" } $SqlReservedKeywords | foreach { if("$SqlInstanceName" -ilike $_) { throw "The SQL Instance Name cannot contain reserved keywords like $_" } } $ForbiddenChars | foreach { if("$SqlInstanceName" -ilike "*$_*") { throw "The SQL Instance Name contains invalid characters ($_)" } } } End { } } |