Skip to content

Instantly share code, notes, and snippets.

@hpmmatuska
Last active August 29, 2015 14:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hpmmatuska/6f0eae4ac80916ccf0c3 to your computer and use it in GitHub Desktop.
Save hpmmatuska/6f0eae4ac80916ccf0c3 to your computer and use it in GitHub Desktop.
The function validate input file (SQL script) for potential dangerous commands. Optional is report and trigger execution.
Function ExecuteSQLscript {
<#
.Synopsis
Execute SQL script
.Description
will trigger sqlexec.exe and display output
.INPUTS
-SQLscript <[System.IO.FileInfo]string>
-SQLServer <[System.IO.FileInfo]string>
-SQLDB <[System.IO.FileInfo]string>
.OUTPUTS
Console output, not suitable for redirect.
ExecuteResults <Int> - errorcode from the sqlexec.exe
.Example
PS C:\ ExecuteSQLscript -SQLscript <file> -SQLServer <instance> -SQLDB <database>
.Notes
Last Updated: April 27, 2015
Version : 1.0
.Link
#>
[cmdletbinding()]
Param(
[Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName, Mandatory=$true)]
[ValidateNotNullorEmpty()]
[String]$SQLscript,
[parameter(Mandatory=$true)]
[ValidateNotNullorEmpty()]
[String]$SQLServer,
[parameter(Mandatory=$true)]
[ValidateNotNullorEmpty()]
[String]$SQLDB
)
invoke-expression ('sqlcmd -i "' + $SQLScript + '" -S "' + $SQLServer + '" -d "' + $SQLDB + '" -E -b -I') | Tee-object -variable ExecuteResults
# here you can put the code for various "$ExecuteResults"...
}
Function ValidateSQL {
<#
.Synopsis
The function validate input file (SQL script) for potential dangerous commands.
.Description
Validate, create report and execute the commands
.INPUTS
-SQLscript <[System.IO.FileInfo]string>
-IllegalCommands <[String[]]>
-SaveReport [Switch]
-ExecuteSQL [Switch]
-SQLServer <[System.IO.FileInfo]string>
-SQLDB <[System.IO.FileInfo]string>
.OUTPUTS
Interactive Console output, not suitable for redirect.
.Example
PS C:\> ValidateSQL
find all *.sql in current directory and will try to validate them
.Example
PS C:\> ValidateSQL c:\sample.sql -SaveReport
verify specified script and create a result report in current directory
The report is created just in case some issue found
.Example
PS C:\> c:\sample.sql | ValidateSQL -ExecuteSQL
validate and execute the script
.Example
PS C:\> ValidateSQL -SQLscript .\SQL_Validation.ps1, C:\BOOTNXT -IllegalCommands Begin, End -Verbose
validate defined scripts with overwritten the default validation phrases
enabled verbouse console output
.Example
PS C:\> ValidateSQL -SQLscript (Get-ChildItem -path c:\sql -Filter *.sql) -SQLServer "Server/Instance" -SQLDB "Test_DB" -ExecuteSQL -Verbose
Pipeline all filter query for SQL scripts to validator function
With option to run all scripts again specified DB
.Notes
Last Updated: April 27, 2015
Version : 1.0
.Link
#>
[cmdletbinding(DefaultParameterSetName = "SQLscript")]
Param(
[Parameter(Position=0, ValueFromPipeline=$true, ValueFromPipelineByPropertyName, ParameterSetName="Path")]
[String[]]$SQLscript = $null,
[parameter()]
[String[]]$IllegalCommands = @(
#Object Level illegal commands
"GRANT SELECT","GRANT DELETE","GRANT INSERT","GRANT UPDATE","GRANT EXEC",
"GRANT EXECUTE","DENY SELECT","DENY DELETE","DENY INSERT","DENY UPDATE","DENY EXEC",
"REVOKE SELECT","REVOKE DELETE","REVOKE INSERT",
#Database Level Illegal Commands
“CREATE USER",“ALTER USER",“DROP USER",
“CREATE ROLE",“ALTER ROLE",“DROP ROLE",
“CREATE APPLICATION ROLE",“ALTER APPLICATION ROLE",“DROP APPLICATION ROLE",
“CREATE DATABASE",“ALTER DATABASE",“DROP DATABASE",
“CREATE RULE",“ALTER RULE",“DROP RULE",
“CREATE TRIGGER",“ALTER TRIGGER",“DROP TRIGGER",
#Server Level Illegal Commands
“CREATE LOGIN",“ALTER LOGIN",“DROP LOGIN",
“CREATE SERVER ROLE",“ALTER SERVER ROLE",“DROP SERVER ROLE",
"SP_CONFIGURE", "SP_RECONFIGURE",
"sp_add_job","sp_add_jobstep","sp_add_schedule","sp_attach_schedule","sp_add_jobserver",
"BACKUP DATABASE","BACKUP LOG", "RESTORE DATABASE","RESTORE LOG",
#Soon to be depreciated statements
"sp_addsrvrolemember","sp_addrolemember","sp_dropsrvrolemember","sp_addapprole","sp_addlogin","sp_addrole",
"sp_adduser","sp_denylogin","sp_dropapprole","sp_droplogin","sp_droprole","sp_droprolemember",
"sp_dropuser","sp_grantdbaccess","sp_grantlogin","sp_revokelogin"
),
[parameter()]
[Switch]$SaveReport = $false,
[parameter()]
[Switch]$ExecuteSQL = $false,
[parameter()]
[String]$SQLServer = $null,
[parameter()]
[String]$SQLDB = $null
)
BEGIN {
Write-Output ''
Write-Verbose 'Looking for SQL scripts'
if (!$SQLscript) { $SQLscript = Get-ChildItem -Attributes !Directory -Include *.sql -Force } #if no param, look for *.sql
if ($SQLscript) { [System.Collections.ArrayList]$a = $SQLscript; $SQLscript | %{ if (!(Test-Path $_ -PathType Leaf)) {$a.Remove($_)}}; $SQLscript = $a; Remove-Variable a} #check if all files exists
if (!$SQLscript) {
Write-Warning "Uh-Oh, nothing to validate found"
Write-Warning "Entered SQLscript paramater does not exists or"
Write-Warning ("No SQL script found at " + (Get-Location) + " path.")
break
}
else {
Write-Output ('Found ' + $SQLscript.count + ' for validation.')
$SQLscript | %{Write-Verbose ("File to be validated: " + $_)}
}
} #check of input paramaters
PROCESS {
$IssuesFound = select-string -path $SQLscript -Pattern $IllegalCommands
if ($IssuesFound) {
Write-Output ''
Write-Warning "Illegal SQL commands are used in the scripts. For more details use verbose paramter or read the log."
$IssuesFound | Write-Verbose
if ($SaveReport) {
$IssuesFound | Export-Clixml SQL_Validation_Report.xml -Force
$IssuesFound | Export-Csv SQL_Validation_Report.csv -Force
}
} # this is the validation report for all illegal matches - just due to logging purposes.
else {Write-Output ''; Write-Output "No illegals commands detected."}
} #Main body of the script, Illegal commands validation
END {
if ($ExecuteSQL) {
If (!$SQLServer) {
Write-Warning "The Target SQL server \ instance is missing. "
$SQLServer = Read-Host -Prompt "Enter SQLServer\Instance or keep blank to specify later: "
}
If (!$SQLDB) {
Write-Warning "The Target Database is missing. "
$SQLDB = Read-Host -Prompt "Enter Database or keep blank to specify later: "
}
Write-Output ''
Write-Verbose "Execution switch detected."
Write-Output ''
$SQLscript | %{
$scriptname = $_
if ($IssuesFound.Filename -contains (split-path $_ -leaf -resolve)) {
Write-Warning ('The file ' + $_ + ' contains dangerous SQL commands.')
$IssuesFound | ?{$IssuesFound.Filename -contains (split-path $scriptname -leaf -resolve)} | %{Write-Warning ('At Line: ' + $_.LineNumber + '`t Error: ' + $_.Line)}
Write-Output ''
$title = "Execute SQL scripts"
$message = "Do you want to execute the SQL Script $scriptname even the unallowed commands were detected?"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Hell Yeah", "Hell yeah, no risk - no fun..."
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "No, are you crazy?"
$show = New-Object System.Management.Automation.Host.ChoiceDescription "&Show", "I want to review the script!"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no, $show)
$result = $host.ui.PromptForChoice($title, $message, $options, 1)
switch ($result) {
0 {Write-Verbose ("Executing " + $scriptname); ExecuteSQLscript -SQLscript $scriptname -SQLServer $SQLServer -SQLDB $SQLDB} # Selected YES
1 {Write-Verbose ("Skipping the script " + $scriptname)} # Selected NO
2 {
notepad.exe ($scriptname)
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 1)
switch ($result) {
0 {Write-Verbose ("Executing " + $scriptname); ExecuteSQLscript -SQLscript $scriptname -SQLServer $SQLServer -SQLDB $SQLDB} # Selected YES
1 {Write-Verbose ("Skipping the script " + $scriptname)} # Selected NO
} #switch
} # Selected SHOW
}
} # write-host $_ " has Issue"
else {
Write-Output ''
Write-Output ('The file ' + $_ + ' is safe to execute.')
$title = "Execute SQL scripts"
$message = "SQL Script $scriptname is safe to execute, would you?"
$yes = New-Object System.Management.Automation.Host.ChoiceDescription "&Yes", "Execute the SQL command"
$no = New-Object System.Management.Automation.Host.ChoiceDescription "&No", "Skip the script"
$options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no)
$result = $host.ui.PromptForChoice($title, $message, $options, 0)
switch ($result) {
0 {Write-Verbose ("Executing " + $scriptname); ExecuteSQLscript -SQLscript $scriptname -SQLServer $SQLServer -SQLDB $SQLDB} # Selected YES
1 {Write-Verbose ("Skipping the script " + $scriptname)} # Selected NO
} # switch
} # write-host $_ " has no Issue"
} # for each sql script
} # Execution switch
} # final return & execution (END)
} # function ValidateSQL
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment