SQL SMO Objects SqlRestore Method (ReadFileList) - sql

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]
}
}

Related

How to correctly store SQL data in a variable?

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.

How to read/fetch data from Oracle SQL database using PowerShell Core?

I have been researching on this for a couple of days but have been going in circles here.
I need to write a script that fetches the data from Oracle db and do something with the data. In my script I will have to fetch data multiple times.
My machine has the SQLDeveloper-21.4.3 which I got from installing InstantClient-Basic-Windows-21.3.0. I use the SQL Developer to connect to the db which is on another machine; this is how I can look into tables, views etc. of the db.
Secondly, this script will be hosted on another server that runs Windows-Server-2012-R2. I am just using my machine to write the script because I cannot use the server to do this. Therefore, I am looking for a solution that requires minimum amount of installing.
Thirdly, we do not have Oracle commercial license. This Oracle db I am trying to access is on the machine installed by a third party that installed some instruments. This company uses Oracle as they collect data on the instruments installed.
I was hoping the solution would be something similar to invoking connection to MS SQL where I downloaded module that gave cmdlets to connect to the MS SQL.
Oracle does have Oracle Modules for PowerShell but neither have I found information on how to use them nor have I understood the little information provided by Oracle on this. For this to work one of the requirement is:
A configuration file and key pair used for signing API requests, with
the public key uploaded to Oracle Cloud using Oracle Cloud
Infrastructure Console. Only the user calling the API should possess
the private key.
I don't know the heck Oracle is talking about here. Like, what is this configuration file, where is it? Where would I get the key pair from for signing API request. What is Oracle Infrastructure Console, where do I get it from? You get the idea.
Link: https://docs.oracle.com/en-us/iaas/Content/API/SDKDocs/powershell.htm
Therefore, I went the .DLL route.
This is what I have done so far:
I installed Oracle.ManagedDataAccess.Core -Version 3.21.61 from NuGet.
Unzipped the package and moved the Oracle.ManagedDataAccess.dll to the location of my script.
The code is:
$OracleDLLPath = "C:\Users\Desktop\CNC_File_Transfer_VSCode\Fastems_NicNet\Oracle.ManagedDataAccess.dll"
$datasource = " (DESCRIPTION =
(ADDRESS =
(PROTOCOL = TCP)
(HOST = 10.50.61.9)(PORT = 1521))
(CONNECT_DATA = (SERVER = DEDICATED)
(SERVICE_NAME = Fa1)
(FAILOVER_MODE = (TYPE = SELECT)
(METHOD = BASIC)
(RETRIES = 180)
(DELAY = 5))))"
$username = "username"
$password = "password"
$queryStatment = "SELECT [PROG_TYPE] FROM NC_PROGRAMS FETCH FIRST 10 ROWS ONLY"
#Load Required Types and modules
Add-Type -Path $OracleDLLPath
Import-Module SqlServer
Write-Host $queryStatment
#Create the connection string
$connectionstring = 'User Id=' + $username + ';Password=' + $password + ';Data Source=' + $datasource
#Creates a data adapter for the command
$da = New-Object Oracle.ManagedDataAccess.Client.OracleDataAdapter($cmd);
#The Data adapter will fill this DataTable
$resultSet = New-Object System.Data.DataTable
#Only here the query is sent and executed in Oracle
[void]$da.fill($resultSet)
#Close the connection
$con.Close()
WRITE-HOST $resultSet
This gives an error though:
Add-Type : Unable to load one or more of the requested types. Retrieve
the LoaderExceptions property for more information.
I am new to programming in general. I would really appreciate if someone could provide detailed steps on resolving this. Thanks in advance.

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")

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 Powershell to Create Backup of Objects

I would like to create a powershell script that I can run to backup objects to file before updating them. My goal is to backup objects before changing them in case something breaks. I would like to pass in parameters to run like the following:
backupobjects.ps1 -servername -databasename -schemaname -objectname -outputdirectory
So if I call this powershell script and pass in parameters the script will connect to the database and find the object and save the CREATE script and save the object to the outputdirectory passed in and put BEFORE_objectname.sql as the filename.
I am just starting in powershell so accepting parameters I have not learned yet.
Any guidance or suggestions would be helpful.
Rather than write it for you, here are a couple of nudges:
1) param is how you pass in parameters in powershell. I like to do it like so:
param (
[string] $server = (Read-Host "Enter a server name"),
[string] $db = (Read-Host "Enter a database name")
)
you then reference $server and $db later in your script as though you'd explicitly initialized them.
2) Most (if not all) objects in SQL server have a Script() method attached to them. For instance take a look at the Table class.
3) You can control how objects are scripted using the ScriptingOptions class. When you invoke the Script() method on an object, pass a ScriptingOptions object as an argument and the scripting behavior will be governed it.