How to correctly store SQL data in a variable? - sql

So I am currently writing a script to create a Jira Issue every morning with all the aborted processes of our Adeptia Broker's. All of this works, except for the part that I get the SQL data and get it into the Jira issue's description.
This is what I use to collect the SQL Server Data a the moment;
$SELECTQUERY = "
SELECT DISTINCT COLUMN, COLUMN, COLUMN, COLUMN
FROM [$DB].[dbo].[$TABLE]
WHERE COLUMN= 'x' AND COLUMN = 'x'
ORDER BY COLUMN DESC
"
try {
# Run SQL Query
Invoke-Sqlcmd -ServerInstance $SI -Database $DB -Username $UID -Password $PASS -Query $SELECTQUERY
$test = $SELECTQUERY.output
CreateJiraIncident -summary $summary -description $test
}
catch {
# Error handling
Write-Warning -Message "Well, the script didn't work..."
break
}
Whenever I call the $SELECTQUERY.output with echo, return or Write-Host it gives me back the correct data. Does anyone know of a different way to store this data in a string so I can send it off to Jira? (No the issue isn't with the Jira part since I can add anything I want to the 'description' parameter it will show up in the Jira Issue.
I really just need a way to store all this data in a string so I can correctly send it.

Related

SQL Server audit extended event metadata change

We have extended event running in SQL Server 2014. We also have a task that run every few minutes and check that the Xevent is running -> Audit the Xevent trace.
I'm trying to find a way (in T-SQL) to audit also changes on the Xevent metadata.
If the Xevent change (by alter), or drop and create.
No need to monitor stop and start session.
I thought about hash function on the Xevent metadata, but I can not find a T-SQL way to get the Xevent string.
Any idea how this can be achieved?
Thanks,
I managed to get the Xevent metadata by using PowerShell SQLPS module.
Then Hash function on the string result:
$server="localhost"
Import-Module sqlps -DisableNameChecking
CD SQLSERVER:\
CD xevent\$server\default\Sessions
$xe=Get-ChildItem |Where-Object {$_.name -eq $XeName}
#$xe.Targets
#$xe.IsRunning
$Xeventmetadata=$xe.ScriptCreate().GetScript()
$Xeventmetadata
#Getting String hash value
function Hash($textToHash)
{
$hasher = new-object System.Security.Cryptography.SHA256Managed
$toHash = [System.Text.Encoding]::UTF8.GetBytes($textToHash)
$hashByteArray = $hasher.ComputeHash($toHash)
foreach($byte in $hashByteArray)
{
$res += $byte.ToString()
}
return $res;
}
Hash("$Xeventmetadata")

TFS Query or SQL Query to Identify Empty Test Plans or Empty Test Suites

We are fairly new to TFS and I have been trying to clean up some of the areas. I can see through a simple TFS query that there are over 180 Test Suites with the name "New suite"... I don't want to try to open each one and look to see if there are test cases assigned to it.
Is there a way to get a report of Empty Test Suites, and maybe Empty Test Plans?
Thanks
Pat
You can use REST API to Get a list of test suites, "testCaseCount" will be included in the response. See below example:
GET https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/fabrikam-fiber-tfvc/_apis/test/plans/1/suites?api-version=1.0
For more information please refer to https://www.visualstudio.com/en-us/docs/integrate/api/test/suites
Besides, you can also get the empty Test Suites or Test Plans by running the sql query in SQL Server, see below sample.
SELECT
[SuiteId]
,[PlanId]
,[ParentSuiteId]
,[Title]
,[TestCaseCountFromMtm]
,[TestCaseCountFromWeb]
FROM [Tfs_CollectionLC].[dbo].[tbl_Suite]
WHERE [TestCaseCountFromMtm]='0' and [TestCaseCountFromWeb]='0'
Update:
If you want to get the Plan and Parent Suite name, in above query the "Title" column will display all the suite name including the Parent Suite name. I didn't find the exact table to get the Plan name, but we can get it via REST API, you can use below sample PowerShell script to get all the Test Plan names. Just copy/paste the script and save it as .ps1 file to run on your client.
$project = "TFVC-Scrum" # Change to your team project name here
$baseUrl = "http://12r2:8080/tfs/CollectionLC" # Change to your TFS Collection URL
$testplanUrl = "{0}/{1}/_apis/test/plans?api-version=1.0" -f $baseUrl, $project
$TestPlans = (Invoke-RestMethod -Uri $testplanUrl -Method Get -UseDefaultCredential).value
$TestPlanResults = #()
foreach($TestPlan in $TestPlans){
$testplanitemUrl = "{0}/{1}/_apis/test/plans/{2}?api-version=1.0&includeDetails=true" -f $baseUrl,$project, $TestPlan.id
$TestPlanItem = Invoke-RestMethod -Uri $testplanitemUrl -Method Get -UseDefaultCredential
$customObject = new-object PSObject -property #{
"TestPlanid"= $TestPlanItem.id
"TestPlanName"= $TestPlanItem.name
}
$TestPlanResults += $customObject
}
$TestPlanResults | Select `
TestPlanid,
TestPlanName

How to determine SQL database replication roles using the Azure PowerShell command Get-AzureRMSqlDatabase

Using the Azure Resource Manager PowerShell commands, is there a simple way to tell whether a database is involved in geo-replication role as either a Primary or Secondary? I used to read the Status property returned by Get-AzureSqlDatabase, and a value of 0 meant that the database was Primary. However, there is no corresponding property returned by Get-AzureRMSqlDatabase; it still returns a status column, but the value is "Online" for both primary and secondary databases.
The reason I need this is that I'm trying to maintain dozens of databases across multiple subscriptions and servers, and I am trying to automate actions that should only be taken on the primary databases.
I found a reasonable solution to this problem, making one extra call per database. The commandlet Get-AzureRmSqlDatabaseReplicationLink does exactly what I needed, with one caveat; I know that I'm not supposed to be passing the same value as both ResourceGroupName and PartnerResourceGroupName, but it seems to work (at least for now), so I'm going with it to avoid having to make one call per resource group in the subscription.
Using that, I was able to create this simple function:
Function IsSecondarySqlDatabase {
# This function determines whether specified database is performing a secondary replication role.
# You can use the Get-AzureRMSqlDatabase command to get an instance of a [Microsoft.Azure.Commands.Sql.Database.Model.AzureSqlDatabaseModel] object.
param
(
[Microsoft.Azure.Commands.Sql.Database.Model.AzureSqlDatabaseModel] $SqlDB
)
process {
$IsSecondary = $false;
$ReplicationLinks = Get-AzureRmSqlDatabaseReplicationLink `
-ResourceGroupName $SqlDB.ResourceGroupName `
-ServerName $SqlDB.ServerName `
-DatabaseName $SqlDB.DatabaseName `
-PartnerResourceGroupName $SqlDB.ResourceGroupName
$ReplicationLinks | ForEach-Object -Process `
{
if ($_.Role -ne "Primary")
{
$IsSecondary = $true
}
}
return $IsSecondary
}
}

Powershell to find the principal/mirror in SQL servers

I would like to know if it is possible to know if a instance of sql server is in mirror/prinicipal by running any sql query? and secondly i want to run this on say 60-80 instances everyday at 4am automatically possible? I would like to use powershell used it before quite easy to use from experience. Tks
It is possible. You will need to play around with SMO objects.
$server = "dwhtest-new"
$srv = New-Object Microsoft.SqlServer.Management.Smo.Server $server
$db = New-Object Microsoft.SqlServer.Management.Smo.Database
$dbs = $srv.Databases
foreach ($db1 in $dbs)
{
$db = New-Object Microsoft.SqlServer.Management.Smo.Database
$db = $db1
$DatabaseName = $db.Name
Write-Host $DatabaseName
Write-Host "MirroringStatus:" $db.MirroringStatus
Write-Host "DBState:" $db.Status
Write-Host
}
If your DB's mirroring is still intact you will recieve 'Synchronized' for MirroringStatus and its its the Primary it will say "Normal" for the status and if its the failover it will say "Restoring". Unfortunately there is no way, that im aware of, to just pull out the status of "Mirror" or "principle". You will jsut have to build logic to check both fo those values.
Restoring
It depends on how are you going to setup the job?
If you want to run it from one central server that collects all the information then SMO would be the way to go with PowerShell. The answer provided by KickerCost can work but would need some more work to be able to run it for multiple servers. It would be best to take his example and turn it into a working function that will allow the server names to be piped in.
If you are going to just run a job locally on each server (scheduled task or SQL Agent job) that may point to the script on a network share, then maybe output that info to a file (like servername_instance.log) you can use a one-liner with SQLPS:
dir SQLSERVER:\SQL\KRINGER\Default\Databases | Select Name, MirroringStatus
KRINGER is my server name, with a default instance. If you have named instances then replace the "default" with the instance name.
Your output from this command would be similar to this:
Name MirroringStatus
---- ---------------
AdventureWorks None
AdventureWorksDW None
Obviously I don't have any databases involved in mirroring.

SQL SMO Objects SqlRestore Method (ReadFileList)

Good afternoon all-
I've searched around quite a bit, and found a few good resources on how to dynamically determine the names of the logical data file names contained within an and SQL .bak file. The SMO method Im working with requires that I pass the ServerName, however my requirement calls for passing the actual file path to the backup. I can get what I need in T-SQL, but I'd really like to determine a way to do it leveraging SMO's. Below is the T-SQL which gets me the information I require:
RESTORE FILELISTONLY
FROM N'C:\Directory\File.bak'
WITH FILE = 1
Unfortunately SqlRestore.ReadFileList(ServerName) will not work, as the backup set has not been restored to a server yet. Essentially I need this information so I can pass it to Restore.RelocateFiles.Add. I'm actually a DBA just dabbling in C#, so if you need more information just let me know and I will try to fill in the gaps. Thanks for any assistance!
The Powershell script below shows how you can read a backup file based on a file path:
$ServerName="SERVER\MYSQLSERVER"
$svrConn = new-object Microsoft.SqlServer.Management.Common.ServerConnection
$svrConn.ServerInstance=$secondaryServerName
$svrConn.LoginSecure = $true
$svr = new-object Microsoft.SqlServer.Management.Smo.Server ($svrConn)
$fullResotrePath = "\\Path\MyDatabase.bak"
$res = new-object Microsoft.SqlServer.Management.Smo.Restore
$res.Devices.AddDevice($fullRestorePath, [Microsoft.SqlServer.Management.Smo.DeviceType]::File)
$dt = $res.ReadFileList($svr)
foreach($r in $dt.Rows)
{
foreach ($c in $dt.Columns)
{
Write-Host $c "=" $r[$c]
}
}