Run sqlquery on multiple server using Powershell - sql

I am trying to run this query
select mirroring_role_desc from sys.database_mirroring where database_id > 4 and mirroring_state is NOT NULL
So the query will basically output the number of databases and just show principal/mirror
like this
I want this query to output to excel file another interesting thing, if any one database in the instance is prinicial/mirror then we can assume the whole instance as principal/mirror.
So in the excel file I want one column with servername\hostname and then the next column to show if it is mirror or principal or none (if none just leave blank) How to do this?
I have tried this,
$ServerInstance = "server1\instance1a "
$Database = " "
$ConnectionTimeout = 30
$Query = "select mirroring_role_desc from sys.database_mirroring where database_id > 4 and mirroring_state is NOT NULL"
$QueryTimeout = 120
$conn=new-object System.Data.SqlClient.SQLConnection
$ConnectionString = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerInstance,$Database,$ConnectionTimeout
$conn.ConnectionString=$ConnectionString
$conn.Open()
$cmd=new-object system.Data.SqlClient.SqlCommand($Query,$conn)
$cmd.CommandTimeout=$QueryTimeout
$ds=New-Object system.Data.DataSet
$da=New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
[void]$da.fill($ds)
$conn.Close()
$ds.Tables
frankly the above code is working fine but the problem is getting the instance name and only single column with principal/mirror INTO a excel file, that is the issue that I am having.
To get a better idea this is what I am trying to achieve:

I wrote a blog post a while back to run a script across all servers in a central management server. You should be able to adapt it fairly easily. Check it out here.

Related

How to modify my code that works with an ACCESS database to work with an SQL database

I have a code running to import CSV files into a Access database. However now I have access to a SQL server and want to use the same code if possible, but no idea what to change to adapt the code
I have a set of running code which uses a connection string I add parameters and it works.
$connectionString="Provider=Microsoft.Ace.OLEDB.12.0; Data Source=$inputDatabase"
$conn = New-Object System.Data.OleDb.OleDbConnection($connectionString)
$conn.Open()
$cmd = $Conn.CreateCommand()
$cmd.CommandText = "INSERT INTO [Tabl1]([date],[zone],[location],[Plugin ID],[CVE],[CVSS],[Risk],[Host],[Protocol],[Port],[Name])
VALUES(#date, #zone, #location, #PluginID, #CVE, #CVSS, #Risk,#Host,#Protocol,#Port,#Name)"```
[void]$cmd.Parameters.Add('#date', [System.Data.OleDb.OleDbType]::DateTime)
[void]$cmd.Parameters.Add('#zone', [System.Data.OleDb.OleDbType]::VarChar)
both code snippets above show how I set up my connection string, and a quick example of how 2 values are set with their corresponding variable type, it is not the whole code . but the snippets I know I need to change to make it work with an SQL server, the main issue being that i dont know which $connectionstring to use with an SQL server, or for example how do I make it so the data source points to the SQL server network address and uses windows authentication.
And on the second code snippet, which type of format do I use, I knwo the variable types but I assume that if I change from ace.oledb.12 , i should change the oldebtype segment. The SQL server is on SQL 13.0.5426
You'll need to update your connection string. Assuming you're using Windows authentication:
$ConnectionString = 'Data Source={0};Initial Catalog={1};Integrated Security=SSPI' -f $ServerInstanceName, $DatabaseName
And you should use the built-in SQL Server client class, System.Net.SqlClient, instead of OLEDB classes.
$conn = New-Object System.Data.SqlClient.SqlConnection $connectionString
And you'll want to update your parameter types:
[void]$cmd.Parameters.Add('#date', [System.Data.SqlDbType]::DateTime)
[void]$cmd.Parameters.Add('#zone', [System.Data.SqlDbType]::VarChar)
Everything else should be more or less identical.
Here's a working PowerShell script that connects to an SQL Server database, fetches data, and fills a data table:
$SqlQuery = 'SELECT * FROM Student WHERE Student_Id = #student_id'
$ConnectionString = 'Data Source={0};Initial Catalog={1};Integrated Security=True' -f $SqlServer, $Database
$SqlConnection = New-Object -TypeName System.Data.SqlClient.SqlConnection -ArgumentList $ConnectionString
$SqlCommand = New-Object -TypeName System.Data.SqlClient.SqlCommand -ArgumentList $SqlQuery, $SqlConnection
$SqlCommand.Parameters.Add('#student_id', [System.Data.SqlDbType]::VarChar, 10).Value = $Student_Id
$DataTable = New-Object -TypeName System.Data.DataTable -ArgumentList 'Student'
try {
$SqlConnection.Open()
$SqlDataReader = $SqlCommand.ExecuteReader()
$DataTable.Load($SqlDataReader)
}
finally {
$SqlConnection.Close()
}
$DataTable

Color coding Invoke-SQL in Powershell

Using invoke-sql I have a PowerShell script that returns results from a SQL Query. That query has the status of several data points local I want to colour code the entire row if the column of Status returns different values. Is this possible as I know you can colour code Charts in PowerShell but not sure how a larger return query would work?
param(
[string] $dataSource = "SQLName",
[string] $database = "DatabaseName",
[string] $sqlCommand = $("Select tbldatafeed.datafeed_name,REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(tbldatafeedhistory.status_id,1,'Running'),2,'Completed'),3,'Faulted'),4,'Warning'),5,'Terminating'),6,'Terminated'),7,'Pending') AS Status,DateDiff(MINUTE,tbldatafeedhistory.start_time, tbldatafeedhistory.end_time) As 'Run Time(minutes)'
from tblDataFeedHistory
left Join tblDatafeed on tbldatafeedhistory.datafeed_id = tbldatafeed.datafeed_id
inner join
(
Select max(start_time) as LatestDate, [datafeed_id]
from tblDataFeedHistory
Group by datafeed_id
) SubMax
on tblDataFeedHistory.start_time = SubMax.LatestDate
and tblDataFeedHistory.datafeed_id = SubMax.datafeed_id
WHERE tbldatafeed.is_active = 1
Order by tbldatafeed.datafeed_id")
)
$connectionString = "Data Source=$dataSource; " + "Integrated Security=SSPI; " + "Initial Catalog=$database"
$connection = new-object system.data.SqlClient.SQLConnection($connectionString)
$command = new-object system.data.sqlclient.sqlcommand($sqlCommand,$connection)
$connection.Open()
$adapter = New-Object System.Data.sqlclient.sqlDataAdapter $command
$dataset = New-Object System.Data.DataSet
write-output $adapter.Fill($dataSet) | Out-Null
$connection.Close()
$dataSet.Tables
}
$FeedID = Invoke-SQL
$FeedID
The output would be a red highlighted line if the column returned Failed, yellow if the Column returns Warning, Green if the column returns Completed.
I've not personally found or seen a reason to do this with SQL data generally, nor do I have any record in my stash of anyone who has.
Anything you write to the screen can have color. It's one of the primary focuses of the …
[Write-Host][1]
Or
[Console]::ForegroundColor]
... cmdlet or .Net class.
However, if you plan to use that data on the pipeline, or elsewhere, then don't use it. Especially if you are not on the newest PowerShell versions. Legacy PowerShell, Write-Host empties the buffer, later PowerShell versions, send it to the Information Stream. As talked by PowerShell inventor Jeffery Snover here:.
http://www.jsnover.com/blog/2013/12/07/write-host-considered-harmful
... Jeffrey Snover change his stance on this as of May 2016.
With PowerShell v5 Write-Host no longer "kills puppies". data is
captured into info stream ...
https://twitter.com/jsnover/status/727902887183966208
https://learn.microsoft.com/en-us/powershell/module/Microsoft.PowerShell.Utility/Write-Information?view=powershell-5.1
However, there are PowerShell modules you can leverage to get really creative with color.
Find-Module -Name '*color*' | Format-Table -AutoSize
You also have several scripts to leverage as is or tweak for your use case.
Format Table Colors in PowerShell
Format the output table colors in PowerShell host with/without conditional colorful formatting.
Download : Write-PSObject.ps1
You do have another option. If you want to call attention, with color to a given screen output line, you can use the ...
Write-Warning
Write-Error
... cmdlets and just accept its default color.
Yet, your question could almost be a duplicate of these Q&A and its accepted answer.
Powershell - Output Color for certain results
Is there a way to specify a font color when using write-output
If you are saying, that you are sending this to a form, then you have to handle color in the form properties code.

Exporting SQL Query to Excel with Username/Password

I am new to this but trying to get it worked out, hoping to find some advice here.
My setup:
Excel 2016 64 Bit
SQL Server 2014 Import and Export Data (64-Bit)
Windows 7 64 Bit
Windows PowerShell ISE (x86)
Microsoft OLE DB Provider for SQL Server
I can export my SQL database perfectly into excel, now I'm just trying to automate it. Here is the code I am currently using:
PowerShell lines
$serverName = "E2\E2SQL";
$databaseName = "*****";
$uid ="*****"
$pwd = "*****"
#the save location for the new Excel file
$filepath = "C:\Users\Bob\Desktop\TEST.xls";
#create a Dataset to store the DataTable
$dataSet = new-object "System.Data.DataSet" "TEST"
#create a Connection to the SQL Server database
$cn = new-object System.Data.SqlClient.SqlConnection "server=$serverName;database=$databaseName;Integrated Security=false; User ID = $uid; Password = $pwd;"
$query= "SELECT JobNo FROM Online;"
#Create a SQL Data Adapter to place the resultset into the DataSet
$dataAdapter = new-object "System.Data.SqlClient.SqlDataAdapter" ($query, $cn)
$dataAdapter.Fill($dataSet) | Out-Null
#close the connection
$cn.Close()
I get an error on
$dataSet = new-object "System.Data.DataSet" "TEST"
I don't really understand that line of code... Anyway any thoughts on how to get this working are greatly appreciated!
I would also be open to exporting to a CSV if that makes it easier.

Is there away to specify which server you want?

The following code or query in powershell allows me to find the number of updates that is needed for a local computer. Is there another way for me to specify which server I want to look at for the number of windows updates. Using -Computername in combination with these script does nothing but gives me error.
$Criteria = "IsInstalled=0 and Type='Software'"
$Searcher = New-Object -ComObject Microsoft.Update.Searcher
$SearchResults = $Searcher.Search($Criteria).Updates
$SearchResults.Count
You can run the code on a remote host via Invoke-Command:
Invoke-Command -Computer 'someserver' -ScriptBlock {
$Criteria = "IsInstalled=0 and Type='Software'"
$Searcher = New-Object -ComObject Microsoft.Update.Searcher
$SearchResults = $Searcher.Search($Criteria).Updates
$SearchResults.Count
}
Change the last line to
$env:COMPUTERNAME, $SearchResults.Count
if you want hostname and number of updates returned instead of just the number of updates.

Script out all SQL objects under particular schema

Is there any way I can script out all the SQL Server objects (tables, SP, functions etc) under a schema?
In our database we have a table containing name of all the schemas and there are more than 500 schema. Some of them are for dev and some are prod. I need to script out all the objects under dev schema and create a new database.
ApexSQL Script is the tool which can be very helpful in this situation. It is the tool which creates SQL scripts for database objects, and it can script all objects into one script or all objects separately.
For this situation here is what you should do:
Select server and the database which you want to script and load them.
Go to the View tab and click the “Object filter” button, then select the “Edit filter” button:
In the Filter editor for all objects select the “Include if:” and “Click here to add filter criteria”:
Select the “Schema”, “Equals” and Enter the desired schema name, then click OK:
Click on the Home tab, check all objects and Click the “Script” button:
In the third step of the Synchronization wizard, under the Script file tab, select if you want to create one script for all objects or for each object individually from the Granularity drop down menu:
In the last step of the Script wizard click the Create button and check out the results – you will have the script which can be executed in the SQL Server Management Studio.
Thanks guys for your reply. I have solved this by generating all the scripts through SSMS and then created a schema only database. Than I dropped all the tables, views SP, functions etc those are not part of the schema I do not need.
It took me around 20 mins to do that. But after all the work is done.
This is PowerShell answer to your problem.
$Server= 'SERVER_NAME'
$Database= 'DATABASE_NAME'
$SmoScriptPath = 'SCRIPT_OUTPUT.SQL'
$Schemas = #("dlo", "deo") # include objects that fall under this schema set
$ObjectTypes = #("StoredProcedures", "Views", "Tables") #object types to be included
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.SMO") | Out-Null
[System.Reflection.Assembly]::LoadWithPartialName("System.Data") | Out-Null
$SmoServer = new-object "Microsoft.SqlServer.Management.SMO.Server" $Server
$SmoServer.SetDefaultInitFields([Microsoft.SqlServer.Management.SMO.View], "IsSystemObject")
$SmoDb = New-Object "Microsoft.SqlServer.Management.SMO.Database"
$SmoDb = $SmoServer.Databases[$Database]
$SmoScr = New-Object "Microsoft.SqlServer.Management.Smo.Scripter"
$SmoScr.Server = $SmoServer
$SmoScr.Options = New-Object "Microsoft.SqlServer.Management.SMO.ScriptingOptions"
$SmoScr.Options.AllowSystemObjects = $false
$SmoScr.Options.IncludeDatabaseContext = $true
$SmoScr.Options.IncludeIfNotExists = $false
$SmoScr.Options.ClusteredIndexes = $true
$SmoScr.Options.Default = $true
$SmoScr.Options.DriAll = $true
$SmoScr.Options.Indexes = $true
$SmoScr.Options.NonClusteredIndexes = $true
$SmoScr.Options.IncludeHeaders = $false
$SmoScr.Options.ToFileOnly = $true
$SmoScr.Options.AppendToFile = $true
$SmoScr.Options.ScriptDrops = $false
$SmoScr.Options.Triggers = $true
$SmoScr.Options.ExtendedProperties = $true
$SmoScr.Options.FileName = $SmoScriptPath
New-Item $SmoScr.Options.FileName -type file -force | Out-Null
Foreach ($ObjectType in $ObjectTypes) {
$Objects = $SmoDb.$ObjectType | where {$_.IsSystemObject -eq $false -and $Schemas.Contains($_.Schema)}
Foreach ($Object in $Objects | where {$_ -ne $null})
{
$SmoScr.Script($Object)
}
}
If you are looking for a solution for getting these objects scripted on a schedule and checked into a GIT Repo Automatically.
Check out the following project I have shared: https://github.com/Drazzing/mssqlobjectstogit
What you get:
Changes to MS SQL Objects over time in [GIT]
Report that shows who Added / Deleted / Changed the objects over time [CSV]
Report Example:
You can use Redgate SQL Compare
or
use management studio generate script feature.