VBA: connect to Oracle db, password has a special symbol - oracle

I'm using this to connect to Oracle:
Set mDBConnection = New ADODB.connection
Dim Rett As String
Rett = "CONNECTSTRING=(DESCRIPTION=(ADDRESS=(PROTOCOL=TCP)"
Rett = Rett & "(HOST=myhost)(PORT=1521))(CONNECT_DATA =(SERVICE_NAME = myservice)));"
Rett = Rett & "uid=" & mDBUser & ";"
Rett = Rett & "pwd=" & mDBPassword & ";"
MsgBox Rett
mDBConnection.Open "DRIVER={Microsoft ODBC for Oracle};" & Rett
This works fine if the password does not contain symbol #.
If it does - I get this error:
[Microsoft][ODBC driver for Oracle][Oracle]ORA-12154: TNS:could not resolve the connect identifier specified
How I can escape this symbol? Maybe I should connect in a different way?

Prior to 11g you couldn't even use # sign in a password since it's part of the standard Oracle connection string (ie, sql*plus> connect scott/tiger#test to connect to the test instance). You were allowed only _, $ and # (referred to as the special characters below) after the first character up to 10g. Apparently, the driver you are using can't handle the required double quotes needed if you use such a character so I'd recommend either changing the driver or the password.
You must enclose the following passwords in double-quotation marks:
Passwords containing multibyte characters.
Passwords starting with numbers or special characters and containing
alphabetical characters. For example:
"123abc"
"#abc"
"123dc$"
Passwords containing any character other than alphabetical characters,
numbers, and special characters. For example:
"abc>"
"abc#",
" "
See Guidelines for Securing Passwords for full info.

ODBC driver "Microsoft ODBC for Oracle" is deprecated for many year, you should not use it. Documentation says "Oracle 7.3x is supported fully; Oracle8 has limited support". Install ODBC driver from Oracle, this should work better.
Your connect command would be like this one:
mDBConnection.Open "DRIVER={Oracle in OraClient11g_home1};dbq=" & mDBServer & ";" & _
"uid=" & mDBUser & ";pwd=""" & mDBPassword & """;"
In case you don't know the exact name of ODBC driver you can search Registry at HKLM\Software\ODBC\ODBCINST.INI\*\Drivers for string SQORA32.dll. The parent key tells the exact name of ODBC driver.
You could also use OLE DB provider like this one:
mDBConnection.Open "Provider=OraOLEDB.Oracle;Data Source=" & mDBServer & ";" & _
"User ID=" & mDBUser & ";Password=""" & mDBPassword & """;"
Like ODBC you don't know whether the driver/provider is installed at all on other machines.

Related

VBS script to scan and install all devices

I'm trying to figure out a way to scan all devices (without drivers installed) and install them one by one automatically.
I've made a simple script that adds/removes a registry value for driver locations, since we have a server with all the current drivers and it's updated frequently, so instead of pointing device manager to that location manually the script does it for me.
Problem is we work in a production environment and we have a lot of different devices to install, and doing it manually takes too long, even with the script i have to click each device and update the driver, the scripts just makes it a little easier by pointing it to the server with the drivers.
So basically i'm try to make the script add the location (this works fine ATM) and them update each device without prompting the user.
Option Explicit
Set ws = WScript.CreateObject("WScript.Shell")
Dim s, ws, rl
rl = "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\"
s = InputBox("Please select what you want to do" & _
vbCrLf & vbTab & "1 - Clear all, set default driver path." & _
vbCrLf & vbTab & "2 - Default path + production drivers" & _
vbCrLf & vbTab & "3 - Default and production path + Skylake drivers")
If s = 1 then
ws.RegWrite rl & "DevicePath", "%SystemRoot%\inf" , "REG_EXPAND_SZ"
ElseIf s = 2 then
ws.RegWrite rl & "DevicePath", "%SystemRoot%\inf; B:\LocalDrivers\; \\ccdsrv01\shares\Resources\Drivers\Client" , "REG_EXPAND_SZ"
ElseIf s = 3 then
ws.RegWrite rl & "DevicePath", "%SystemRoot%\inf; B:\LocalDrivers\; \\ccdsrv01\shares\Resources\Drivers\Client; \\ccdsrv01\shares\Resources\PreProd\SkyBay (Skylake-SunrisePoint)\New" , "REG_EXPAND_SZ"
End If

Using VBS and the registry to determine which version and 32 vs. 64 bit oracle drivers are installed

I'd like to use VBS to read the registry to list some info on a server including the drivers.
VBS:
REM Run this file with the following command:
REM cscript drivers.vbs | clip
WScript.Echo "------------------------------------------------"
Const HKEY_LOCAL_MACHINE = &H80000002
'Get Server Name
Set wshNetwork = WScript.CreateObject( "WScript.Network" )
strComputerName = wshNetwork.ComputerName
WScript.Echo "Computer Name: " & strComputerName
'Get Driver Names
strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers"
objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes
For i = 0 to UBound(arrValueNames)
strValueName = arrValueNames(i)
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Wscript.Echo arrValueNames(i) & " -- " & strValue
Next
Set objShell = WScript.CreateObject("WScript.Shell")
'Get Oracle Environment variables
WScript.Echo "TNS_ADMIN=" & objShell.Environment("SYSTEM").Item("TNS_ADMIN")
WScript.Echo "ORACLE_HOME=" & objShell.Environment("SYSTEM").Item("ORACLE_HOME")
WScript.Echo "------------------------------------------------"
Output:
------------------------------------------------
Computer Name: WLDL2532
SQL Server -- Installed
Client Access ODBC Driver (32-bit) -- Installed
iSeries Access ODBC Driver -- Installed
SQL Server Native Client 10.0 -- Installed
**Oracle in OraClient11g_home1 -- Installed**
IBM DB2 ODBC DRIVER - DB2_976_64 -- Installed
IBM DB2 ODBC DRIVER -- Installed
ODBC Driver 11 for SQL Server -- Installed
DataDirect 6.1 Sybase Wire Protocol -- Installed
SQL Server Native Client 11.0 -- Installed
TNS_ADMIN=C:\WINDOWS\TNS
ORACLE_HOME=
------------------------------------------------
Question
I'd like to know how to seperately list if the 32 bit driver or the 64 bit Oracle driver is installed. I have both on my machine, but it doesn't indicate which. Presumably, it can mean both or either, I assume. Normally, if a 32 bit driver were found, I'd expect to see "32" in the name. Can you help? Thank you!
if you know where to best look in the registry for this info, that would be helpful, too, if you don't know the code off hand.
According to your VBS code the question should be: Using VBS and the registry to determine which version and 32 vs. 64 bit of ODBC drivers are installed
There are many other drivers available for Oracle, e.g. OleDB, ODP.NET, JDBC, etc.
In order to get 32 and 64 bit you can do it in two ways
Either run the VBS in different scripting host, i.e.
For 64 Bit: >c:\Windows\system32\cscript.exe Drivers.vbs
For 32 Bit: >c:\Windows\SysWOW64\cscript.exe Drivers.vbs
Or modify the VBS script in order to interrogate 32 and 64 Bit path in Registry:
strComputer = "."
Set objRegistry = GetObject("winmgmts:\\" & strComputer & "\root\default:StdRegProv")
strKeyPath = "SOFTWARE\ODBC\ODBCINST.INI\ODBC Drivers"
objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes
For i = 0 to UBound(arrValueNames)
strValueName = arrValueNames(i)
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Wscript.Echo arrValueNames(i) & " -- 64 Bit " & strValue
Next
strKeyPath = "SOFTWARE\Wow6432Node\ODBC\ODBCINST.INI\ODBC Drivers"
objRegistry.EnumValues HKEY_LOCAL_MACHINE, strKeyPath, arrValueNames, arrValueTypes
For i = 0 to UBound(arrValueNames)
strValueName = arrValueNames(i)
objRegistry.GetStringValue HKEY_LOCAL_MACHINE,strKeyPath,strValueName,strValue
Wscript.Echo arrValueNames(i) & " -- 32 Bit " & strValue
Next
Another note: TNS_ADMINand ORACLE_HOME can be defined by environment variable, however you can defined them also in the Registry. Check for 64 bit
HKLM\SOFTWARE\ORACLE\Key_{ORACLE_HOME_NAME}\TNS_ADMIN
and
HKLM\SOFTWARE\ORACLE\Key_{ORACLE_HOME_NAME}\ORACLE_HOME
and for 32 bit
HKLM\SOFTWARE\Wow6432Node\ORACLE\Key_{ORACLE_HOME_NAME}\TNS_ADMIN
and
HKLM\SOFTWARE\Wow6432Node\ORACLE\Key_{ORACLE_HOME_NAME}\ORACLE_HOME

Dependencies for VB6 connection to Oracle DB

I have an old VB6 app which uses ADO to connect to SQL server databases, as:
Dim cnServer As New ADODB.Connection
cnServer.Provider = "sqloledb"
sConnectString = "Server=" & txtServer.Text & ";" & _
"Database=" & txtDatabase.Text & ";" & _
"User ID=" & txtUserID.Text & ";" & _
"Password=" & txtPassword.Text & ";" & _
"Connect timeout=10"
cnServer.Open sConnectString
...which has always worked. But now I need to modify it to connect to an Oracle 11g database. I found this article and modified the code to:
Dim cnServer As New ADODB.Connection
cnVLServer.Provider = "OraOLEDB.Oracle"
sConnectString = "Server=" & txtServer.Text & ";" & _
"Data Source=" & txtDatabase.Text & ";" & _
"User ID=" & txtUserID.Text & ";" & _
"Password=" & txtPassword.Text & ";" & _
"Connect timeout=10"
cnVLServer.Open sConnectString
...but when I run it, I get an error that reads 3706, Provider cannot be found. It may not be properly installed. This happens on my development VM (which -- don't laugh -- is still on Win2K Pro), and also on my test machine (which uses Win XP).
Some further searching indicated that oracore11.dll is a dependency, so I went to Oracle's download site and pulled down this DLL as part of a .zip file containing what I take to be the full suite of Windows-related coding tools. However the error still occurs even if I place this DLL in the same folder with my VB6 executable. And when I try to register the DLL, the attempt just generates another error: The specified module could not be found.
Before any further thrashing with what may be a wrong path or an unsolvable problem in the first place, I figured I should check in and see the best/easiest way to get a VB6 app to connect to Oracle in the first place. My goal here is to have this VB6 app be as portable as possible, not requiring any pre-installed packages to work, and having the minimum set of dependencies be easily passed around with the .exe itself. (For reference, this VB6 app is not a commercially-distributed product, just an internally-used testing tool within my own department at work. It takes flat-file fixed width data, parses it, then generates the SQL code to insert it to the DB.)
To configure an Oracle Database Instant, you must:
Install the Oracle Database Instant Client and its ODBC driver on your system;
Set the TNS_ADMIN environment variable;
Configure a tnsnames.ora configuration file for your client.
Please refer to this link, for further details...

How to get clientsitename and object status in windows 2000

As we know it's easy to get client site name in windows 2003 via WMI_NTdomain.clientsitename, object status by WMI_NTdomain.status , but that class doesn't exist in Windows 2000. So can you show me how to get those value by script or command line?
My old system is still running well on windows 2000, i don't want to change it at now.
Grab HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\services\Netlogon\Parameters\DynamicSiteName with reg.exe, vbscript, or your favorite scripting/programing language.
Edit:
I admit that I haven't seen W2k for some time now. Does this VB Script output usefull information:
option explicit
dim adSys
Set adSys = CreateObject("ADSystemInfo")
WScript.Echo "SiteName=" & adSys.SiteName
'WScript.Echo "Computername DN=" & adSys.ComputerName
'WScript.Echo "Username DN=" & adSys.UserName
'WScript.Echo "DomainDNSName (Comp)=" & adSys.DomainDNSName
'WScript.Echo "DomainShortName (Comp)=" & adSys.DomainShortName
'WScript.Echo "ForestDNSName (Comp)=" & adSys.ForestDNSName
You could also use the WMI ScriptOMatic to search for the relevent class.

Calling SFTP process from VBA code

problem - Store key in cache Question stop VBA app
I use pscp.exe in order to transfer files from windows to Linux machine.
Remark: pscp.exe exists in my VBA code (that client is part of the PuTTY tools)
When I copy files from my PC to any new Linux machines I get the question "Store key in cache? (y/n)" and this interrupts my VBA application (VBA application stopped on sftp process).
I need advice how to ignore the question "Store key in cache? (y/n)". Or maybe automatically sending a "y" key from my VBA code? Or other solution as defined in the PC registry before running the pscp.exe? But how to do that?
Example from WIN XP command line (cmd)
Remark: 192.9.200.120 (Linux server IP address)
"D:\documents and settings\udavid\pscp.exe" -sftp -l root -pw pass123
"D:\Documents and Settings\udavid\Desktop\scan_ip.ksh" 192.9.200.120:/var/tmp
CMD output :
The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 1024 15:e1:ce:4f:8e:4e:7b:61:14:c3:df:3c:b1:50:67:b6
If you trust this host, enter "y" to add the key to
PuTTY's cache and carry on connecting.
If you want to carry on connecting just once, without
adding the key to the cache, enter "n".
If you do not trust this host, press Return to abandon the
connection.
Store key in cache? (y/n)
Example of CMD output if I use -batch flag (pscp.exe -batch)
The server's host key is not cached in the registry. You
have no guarantee that the server is the computer you
think it is.
The server's rsa2 key fingerprint is:
ssh-rsa 2048 d5:80:49:7f:69:f1:29:7c:1f:99:ec:c9:f4:b2:6f:a0
Connection abandoned.
Lost connection
--- Example from my VBA code ---
Const cstrSftp As String = """D:\documents and settings\udavid\pscp.exe"""
Dim strCommand As String
Dim pUser As String
Dim pPass As String
Dim pHost As String
Dim pFile As String
Dim pRemotePath As String
pUser = "root"
pPass = "pass123"
pHost = "xxx.xxx.xxx.xxx" xxx.xxx.xxx.xxx - any server new IP
pFile = """D:\Documents and Settings\udavid\Desktop\scan_ip.ksh"""
pRemotePath = "/var/tmp"
strCommand = cstrSftp & " -sftp -l " & pUser & " -pw " & pPass & " " & pFile & " " & pHost & ":" & pRemotePath
Debug.Print strCommand
Shell strCommand, 1
You can use Shell "cmd /c echo y | " & strCommand, 1 as a suggested quick hack.
I use a home-made cExec class to pipe output and to selectively respond to putty warnings like this
With New cExec
.Run "d:\downloads\pscp.exe", sParams, True
Do While Not .AtEndOfOutput
If InStr(.ReadLineOutput, "(y/n)") Then
.WriteInput "y"
End If
Loop
End With
Try this :
echo y|"C:\Program Files\PuTTY\pscp.exe" -sftp -l root -pw pass123 C:\scan_ip.ksh $server:/var/tmp
It will "press" y to your program standar input.
The help (pscp /?) gives you the answer.
You should pass -batch to disable all prompts like that.
You may also want to quote your parameters correctly so spaces and quotes in the values don't break things.

Resources