Connecting to DB2 using PowerShell - 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.

Related

Scheduling a Powershell process does not yield the same results as when I run it manually

I wrote a small PowerShell script that I am using to query the Server Log, clean the return values and use some of the results to perform some server maintenance. However, when I schedule the save to file piece is not writing the whole content to the file and it is getting truncated, just like what I ma posting below, exactly. As you can observe, the end of the file is truncated with three dots added to replace the missing values:
Login failed for user 'sa'. Reason: An error occurred while evaluating the password. [CLIENT: 2...
However, if I run the code manually with Local Admin access, the content gets saved to the local file like this, exactly:
Login failed for user 'sa'. Reason: An error occurred while evaluating the password. [CLIENT: 112.103.198.2]
Why is this the case when I schedule the process or PS file to run under a schedule. BTW, I tried to run it under the SYSTEM context with full or highest privileges and even used the same Admin account that I use to run it manually to schedule and still do nt get the full content of the event that I save.
This is creating an issue and I am not able to use the content to process the IP.
Here is the PS code that I am using to query and save the content to file:
$SQL = 'C:\SQL.txt'
Remove-Item $SQL -ErrorAction Ignore
Get-EventLog -LogName Application | Where-Object {$_.EventID -eq 18456} |
Select-Object -Property Message | Out-File $SQL
The problem lies with out-file because it has a default character limit of 80 per line.
You can change it with -width property and give a value of say 200. However set-content doesn't have these limits set in. So it might be a more suitable option.
All that being said, I am not sure why it does it one way when ran manually vs another when the system runs it.
Out-file defaults to unicode when writing files
set-file defaults to ascii when writing files

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

Changing ODBC connection servername parameter using PowerShell

I need an automatic way to change only servername parameter of a connection to a PostgreSQL database.
The only way I found in my research is through a PowerShell script following instructions from this link. It states that Set-OdbcDsn can modify, add or delete connection properties.
I have the following script:
$DsnArray = Get-OdbcDsn -DriverName "PostgreSQL ANSI" |
Where-Object {($_.Attribute["Servername"] -eq "oldServer")}
Set-OdbcDsn -InputObject $DsnArray -SetPropertyValue "Servername=newServer"
My problem is that the script is changing indeed the servername parameter, but deletes Port, Username, Database, SSlMode, Description parameters and I need them to remain as they are because they differ to each connection.
What am I missing in the commands? If you know a different way to achieve the same purpose of automatically modify existing connection strings, please let me know.

Configure SharePoint 2010 UPS with PowerShell

SOLUTION FOUND: For anyone else that happens to come across this problem, have a look-see at this: http://www.harbar.net/archive/2010/10/30/avoiding-the-default-schema-issue-when-creating-the-user-profile.aspx
TL;DR When you create UPS through CA, it creates a dbo user and schema on the SQL server using the farm account, however when doing it through powershell it creates it with a schema and user named after the farm account, but still tries to manage SQL using the dbo schema, which of course fails terribly.
NOTE: I've only included the parts of my script I believe to be relevant. I can provide other parts as needed.
I'm at my wit's end on this one. Everything seems to work fine, except the UPS Synchronization service is stuck on "Starting", and I've left it over 12 hours.
It works fine when it's set up through the GUI, but I'm trying to automate every step possible. While automating I'm trying to include every option available from the GUI so that it's present if it ever needs to be changed.
Here's what I have so far:
$domain = "DOMAIN"
$fqdn = "fully.qualified.domain.name"
$admin_pass = "password"
New-SPManagedPath "personal" -WebApplication "http://portal.$($fqdn):9000/"
$upsPool = New-SPServiceApplicationPool -Name "SharePoint - UPS" -Account "$domain\spsvc"
$upsApp = New-SPProfileServiceApplication -Name "UPS" -ApplicationPool $upsPool -MySiteLocation "http://portal.$($fqdn):9000/" -MySiteManagedPath "personal" -ProfileDBName "UPS_ProfileDB" -ProfileSyncDBName "UPS_SyncDB" -SocialDBName "UPS_SocialDB" -SiteNamingConflictResolution "None"
New-SPProfileServiceApplicationProxy -ServiceApplication $upsApp -Name "UPS Proxy" -DefaultProxyGroup
$upsServ = Get-SPServiceInstance | Where-Object {$_.TypeName -eq "User Profile Service"}
Start-SPServiceInstance $upsServ.Id
$upsSync = Get-SPServiceInstance | Where-Object {$_.TypeName -eq "User Profile Synchronization Service"}
$upsApp.SetSynchronizationMachine("Portal", $upsSync.Id, "$domain\spfarm", $admin_pass)
$upsApp.Update()
Start-SPServiceInstance $upsSync.Id
I've tried running each line one at a time by just copying it directly into the shell window after defining the variables, and none of them give an error, but there has to be something the CA GUI does that I'm missing.
For anyone else that happens to come across this problem, have a look-see at this: http://www.harbar.net/archive/2010/10/30/avoiding-the-default-schema-issue-when-creating-the-user-profile.aspx
TL;DR When you create UPS through CA, it creates a dbo user and schema on the SQL server using the farm account, however when doing it through powershell it creates it with a schema and user named after the farm account, but still tries to manage SQL using the dbo schema, which of course fails terribly.
The workaround is to put my code into its own script file, and then use Start-Process to run the script as the farm account (it's a lot cleaner than the Job method described in the linked article):
$credential = Get-Credential ("$domain\spfarm", $SecureString)
Start-Process -FilePath powershell.exe -ArgumentList "-File C:\upsSync.ps1" -Credential $credential

Powershell connect to firebird

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.