Powershell connect to firebird - powershell

Hey I was wondering how one could connect to a firebird database (gdb) file from within powershell. Is there a way to use the .net data provider for firebird to connect? Is there a way to connect with System.Data.Odbc.OdbcConnection to firebird?

function Get-ODBC-Data{
param([string]$query=$(throw 'query is required.'))
$conn=New-Object System.Data.Odbc.OdbcConnection
$connStr = "Driver={Red Database/Firebird driver};Server=localhost;Port=****;Database=*.fdb;Uid=user;Pwd=userpassword;"
$conn.ConnectionString= $connStr
$conn.open
$cmd=new-object System.Data.Odbc.OdbcCommand($query,$conn)
$cmd.CommandTimeout=15
$ds=New-Object system.Data.DataSet
$da=New-Object system.Data.odbc.odbcDataAdapter($cmd)
[void]$da.fill($ds)
$ds.Tables[0]
#Write-Output $ds.Tables[0].rows.count
$conn.close()
}
$query = #"
select count(*)
from UNIFO_PAYMENT U
join DOCUMENT D on D.ID = U.ID
"#
$result = Get-ODBC-Data -query $query

The code from #Alexandr is from https://www.andersrodland.com/working-with-odbc-connections-in-powershell/
I suggest you read the entire thing. While he isn't exactly explaining the code either, I think it's fairly self-documenting, the only information that is missing, is how to get/use the Firebird driver.
You can get the ODBC driver installer from firebird https://www.firebirdsql.org/en/odbc-driver/
After Installing it, open windows ODBC administration (odbcad32.exe), check the drivers tab to make sure that the "Firebird/Interbase(r) driver" is there.
From here you can either use that driver name to run #Alexandr 's code
$connStr = "Driver=Firebird/Interbase(r) driver;Server=localhost;Port=****;Database=*.fdb;Uid=user;Pwd=userpassword;"
OR Go to either the User DSN tab, or the system DSN tab. Click add, select the firebird driver, set up the DSN with a name, the path to your database and the other required database registration info you normally would. Keep the DSN name simple, it's an identifier you will use.
Then you can simply replace the $constr with
$connStr = "DSN=YourDsnName;"

Yes, powershell allows you to create .Net classes and call .Net methods. See here. So with little trouble you can convert your C# code to powershell.

Related

How to get the database backup path from a server using powershell?

I have been looking for the powershell commands for getting the backup path of a database in an sql server. I would be providing sever name and database name as input. Could some one help me with the solution so that I can achieve my requirement.
Note: I just need the path of the database backup. I need not to do any back up of that database in a path.
Thanks in advance.
Sudhir
So.... couple of things.
A SQL Server instance (sounds like you're asking about SQL Server), has a default backup location, which can be overridden at the time of a backup. If you want to see an instance's default backup location, I'd use something like this:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo")
$i = New-Object 'Microsoft.SqlServer.Management.Smo.Server' '(local)'
$i.Settings.BackupDirectory
I'm using SQL Server Management Objects (SMO) here. I've created an instance object ($i), and I've queried the BackupDirectory property in the Settings collection to get the desired path.
If you don't like SMO, you can also get this information from the registry; see this article for help there.
Adding an answer here (since I can't add comments yet), there is also the option to use the newer SQLServer module in powershell. Just run a query to get the data you need. This is for a local SQL Express instance, update the name as needed.
Import-Module SqlServer
$bkppath = Invoke-Sqlcmd -Query "SELECT SERVERPROPERTY('InstanceDefaultBackupPath')" -ServerInstance ".\SQLExpress"
$bkppath.Column1
As an added bonus, if you'd like to delete the oldest backups just run this line, updating the best number of days to keep (AddDays function) (using bits of Pinal code from https://blog.sqlauthority.com/2018/04/02/sql-server-powershell-script-delete-old-backup-files-in-sql-express/ ):
Get-ChildItem $bkppath.Column1 -Recurse | Where-Object { $_.LastWriteTime -lt (Get-Date).AddDays(-7) } | Remove-Item -Recurse

Grant read permission for MSysObjects

I need to get the metadata of some hundred MS Access DBs, so I need to automate the process of metadata gathering.
I want to query stuff described here, but before I can query the DBs I need read access to MSysObjects tables.
I Keep getting following error:
Record(s) cannot be read; no read permission on 'MsysObjects'.
so I dug deeper:
I've read the article about similar issues in the C# section (see here and also this one).
I put together a simple script which works well for creating tables and so on, but I am having problems to setup the read access.
$ScrUsr = $(whoami)
Write-Host $ScrUsr
$cmd = "GRANT SELECT ON MSysObjects TO [$ScrUsr]"
Write-Host $cmd
Function Invoke-ADOCommand($Db)
{
$connection = New-Object -ComObject ADODB.Connection
$connection.Open("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$db;" )
$command = New-Object -ComObject ADODB.Command
$command.ActiveConnection = $connection
$command.CommandText = $cmd
$rs = $command.Execute()
$connection.Close()
}
$Db = "C:\Temp\test1.accdb"
Invoke-ADOCommand -db $Db
Executing the Script throws me following Error reason:
Cannot open the Microsoft Office Access database engine workgroup information file.
How can I allow read permission on MSysObjects?
There are two issues you must address:
Your code will use the Access security account "Admin" when interacting with the Access ACCDB database. Other Access security accounts are only available if you have implemented Access user-level security (ULS), but that feature is only available for MDB format databases. Therefore, with ACCDB, you can't GRANT anything to any account other than "Admin".
You must include the location of the "System database" in your connection string.
If you don't know where to find the System database, open Access and check the output from this statement in the Immediate window. (Ctrl+g will open the Immediate window)
Debug.Print Application.DBEngine.SystemDb
My System database is C:\Users\hans\AppData\Roaming\Microsoft\Access\System1.mdw Substitute yours in the code example below.
I'm not really proficient with Powershell, but this example ran without error for me. (Be sure to change both $Db and $SystemDb.)
$ScrUsr = $(whoami)
Write-Host $ScrUsr
$cmd = "GRANT SELECT ON MSysObjects TO Admin;"
Write-Host $cmd
Function Invoke-ADOCommand($Db, $SystemDb)
{
$connection = New-Object -ComObject ADODB.Connection
$ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=$db;Jet OLEDB:System database=$SystemDb;"
Write-Host $ConnectionString
$connection.Open($ConnectionString)
$discard = $connection.Execute($cmd)
$connection.Close()
}
$Db = "C:\Users\hans\AccessApps\Sample.accdb"
$SystemDb = "C:\Users\hans\AppData\Roaming\Microsoft\Access\System1.mdw"
Invoke-ADOCommand -db $Db -SystemDb $SystemDb

how to connect oracle database and run query by powershell

How can I connect to an Oracle database (11g)? I have a list of oracle servers and I want to execute a query on them from Jump Server (the Jump server has Powershell v2).
Servers are accessible from Jump Server as I am able to access them by UNC path.
Update:
I know it can be done by using ODP.Net connector. But i don't want to use it due to approval.
You can try the method using an OleDbConnection described here
function Get-OLEDBData ($connectstring, $sql) {
$OLEDBConn = New-Object System.Data.OleDb.OleDbConnection($connectstring)
$OLEDBConn.open()
$readcmd = New-Object system.Data.OleDb.OleDbCommand($sql,$OLEDBConn)
$readcmd.CommandTimeout = '300'
$da = New-Object system.Data.OleDb.OleDbDataAdapter($readcmd)
$dt = New-Object system.Data.datatable
[void]$da.fill($dt)
$OLEDBConn.close()
return $dt
}

Powershell Invoke-sqlcmd keeping connection open and trying to reuse it

I have a Powershell script that uses invoke-sqlcmd to apply scripts to a series of development databases. I loop through a list of scripts and compare it to the current release level of the database and then apply the required scripts to get the DB to the release level it needs to be at. Certain databases are reference databases and are in a READ_ONLY state. I connect to those database run an alter DB script setting them to READ_WRITE apply the script then change the back to READ_ONLY. Overall the script works well, the issue is it looks like when PowerShell first opens a connection to the database and applies the first script and then goes to alter the DB back to READ_ONLY the database has objects locked. I've traced it back to the previous connection and a Shared_Transaction_Workspace lock (sys.dm_tran_locks) for what looks to be the previous powershell connection. Why is this connection still open after the invoke-sqlcmd has completed and is there anything I can do about it? Can I force invoke-sqlcmd to use a new connection for each invocation of the cmdlet?
I have tried a messy fix killing the offending connection and then retrying the connection but I think there is something better.
I've always done this and it seems to work:
[System.Data.SqlClient.SqlConnection]::ClearAllPools()
Well, I know that this is a very old post and the people from Microsoft told that fixed this issue (as told the article mentioned by David Brabant) but maybe I'm not the luckiest guy and have to make an workaround to make it happens.
Even running Microsoft SQL Server 2012 (SP1) - 11.0.3128.0 (X64) I had the same issue and after make some researches I got a way to get some parameter from Invoke-Sqlcmd as output so I can get the Session ID of the current user process with the built-in ##SPID global variable from the SQL Server and make a connection with ADO.NET to execute a KILL clause to close the opened connection.
So let's to the workaround applied in my case
#Invoke the Invoke-Sqlcmd to execute an script from a file
Invoke-Sqlcmd -Server "[SERVER_NAME]" -Database [DATABASE_NAME] -Username [USER] -Password [PASSWORD] -InputFile [DOT_SQL_FILE_PATH]
#Invoke the Invoke-Sqlcmd to execute a inline SQL statement to get the SessionID as a Powershell variable
$SQLSession = Invoke-Sqlcmd -Server "[SERVER_NAME]" -Database [DATABASE_NAME] -Username [USER] -Password [PASSWORD] -query "select ##spid as SessionID"
# Build query to execute KILL clause
$DbQuery = "KILL " + $SQLSession.SessionID;
# Create SQL connection with ADO.NET
$DbConnection = New-Object System.Data.SqlClient.SqlConnection
$DbConnectionString = "Server = [SERVER_NAME]; Database = [DATABASE_NAME]; User ID=[USER]; Password=[PASSWORD];"
$DbConnection.ConnectionString = $DbConnectionString
$DbConnection.Open()
# Create SQL command for KILL clause
$DbCommand = New-Object System.Data.SQLClient.SQLCommand
$DbCommand.Connection = $DbConnection
$DbCommand.CommandText = $DbQuery
# Execute KILL clause
$DbCommand.ExecuteNonQuery()
# Close connection
$DbConnection.Close()
I hope that it helps
Even though I am using the newest version of SSMS (Version 16.5.3 - Build 13.0.16106.4), I still get this issue. I haven't figured out what the "right" way of forcing the connection closed is, but I have a work-around that is simple and resolves the issue for me. If you just need to get the connection off the database, you can do the following:
Run normal command(s)
Invoke-Sqlcmd -ServerInstance "SOME_SERVER" -Database "SOME_DB" ...
When you are ready to eliminate the connection from the database:
Invoke-Sqlcmd -ServerInstance "SOME_SERVER" -Database "SOME_DB" -Query "use [master];"
This will switch the connection to master, thus removing it from the database of interest. If you absolutely need the connection closed, I think you need to resort to SqlClient or such.

Connecting to DB2 using PowerShell

I'm trying to connect to a DB2 database and execute some queries. I had it working a few days ago, but now it's giving some really strange errors and I can't figure out why.
The PowerShell connection code
$connection = New-Object System.Data.OleDb.OleDbConnection("Provider=IBMDADB2;Database=X;HostName=X;Protocol=TCPIP;Port=X;Uid=X;Pwd=X;CurrentSchema=X");
$ds = New-Object "System.Data.DataSet"
$da = New-Object System.Data.OleDb.OleDbDataAdapter($QuerySQL, $connection)
$da.Fill($ds)
$ds.Tables[0].Rows |
select * -ExcludeProperty RowError, RowState, HasErrors, Name, Table, ItemArray |
Export-Csv "c:\Scripts\results.csv" -encoding "unicode" -notype
The error I'm seeing:
Exception calling "Fill" with "1" argument(s): "No error message available, result code: E_UNEXPECTED(0x8000FFFF)."
Anybody got any ideas why this is cropping up?
I've got other scripts that use Fill() in the exact same way an don't produce errors, so this is really baffling me!
Ok, I've figured it out.
You need to run powershell as admin to use the DB2 driver. Why this is, I don't know, but that's how I fixed it!
You need to add the user to the DB2Users or DB2Admns groups. The local Administrators group works, too, but for security reasons the other two groups are more appropriate. These groups are typically created by default on the server to which you install DB2. They are local groups.