Im quite new to powershell scripting so go easy. If anyone here works with oracle (or not, its just a file with addresses) , Im trying to parse a TNSnames.ora file and build a set of commands in to talk to each database. There are 2 different types of entry, 1 for single instance entries where we have ADDRESS= but another type where its a clustered environment and there could be multiple entries so here we have ADDRESS_LIST=
From looking others ideas, the goal is to strip it down for each entry to variables such as
name=entry1;address=,host=;port=;service_name=
and once we do we can run commands on those parameters.
TNSnames.ora file starts here
ENTRY1.world =
(DESCRIPTION =
(ADDRESS = (PROTOCOL = TCP)(HOST = HOST1)(PORT = 1521))
(CONNECT_DATA =
(SERVER = DEDICATED)
(SERVICE_NAME = service1)
)
)
ENTRY2.WORLD =
(DESCRIPTION =
(ADDRESS_LIST =
(LOAD_BALANCE = OFF)
(FAILOVER = ON)
(ADDRESS = (PROTOCOL = TCP)(HOST = HOST3)(PORT = 1521))
(ADDRESS = (PROTOCOL = TCP)(HOST = HOST4)(PORT = 1522))
)
(CONNECT_DATA =
(SERVICE_NAME = service2)
(FAILOVER_MODE =
(TYPE = SESSION)
(METHOD = BASIC)
(RETRIES = 2)
(DELAY = 2)
)
)
)
# tnsnames.ora ends
So for the above 2 entries we’d have
name=ENTRY1;address=,host=HOST1;port=1521;service_name=service1
But we would want multiple sets for the second entry
name=ENTRY2;address=,host=HOST3;port=1521;service_name=service2
name=ENTRY2;address=,host=HOST4;port=1522;service_name=service2
I think if found ADDRESS_LIST there has to be an array of entries for each distinct ADDRESS= line.
how to go about that?
Heres my attempt, works for first ENTRY but fails for second due to ADDRESS_LIST entry
function Get-OraTnsAdminEntries
{
param
(
[System.IO.FileInfo] $File
)
begin {}
process
{
[object[]] $tnsEntries = @()
if ($_)
{
$File = [System.IO.FileInfo] $_
}
[string] $data = gc $File.FullName | select-string -PAttern '#' -NotMatch
$lines = $data.Replace("`n","").Replace(" ","").Replace("`t","").Replace(")))(","))(").Replace(")))",")))`n").Replace("=(","=;").Replace("(","").Replace(")",";").Replace(";;",";").Replace(";;",";").Split("`n")
foreach ($line in $lines | where{$_ -ne ""} )
{
$line
if ($line.Trim().Length -gt 0)
{
$lineBreakup = ConvertFrom-StringData -StringData $line.Replace(";","`n") | where{$_ -ne ";"} | where{$_ -ne ""}
IF (([regex]::Matches($line, "ADDRESS" )).count -eq 1)
{
$entryName = $line.Split("=")[0] #Everything to the left of the first "=" in "$Service,$Service.WORLD=;DESCRIPTION=;ADDRESS=;PROTOCOL=$Protocol;Host=$Hostname;Port=$Port;CONNECT_DATA=;SERVICE_NAME=$Service;"
$tnsEntry = New-Object System.Object
$tnsEntry | Add-Member -type NoteProperty -name Name -value $entryName.trim(";")
$tnsEntry | Add-Member -type NoteProperty -name SimpleName -value ($entryName.Split(",")[0].Trim().Split(".")[0].Trim().trim(";"))
$tnsEntry | Add-Member -type NoteProperty -name Protocol -value $lineBreakup["PROTOCOL"]
$tnsEntry | Add-Member -type NoteProperty -name Host -value $lineBreakup["Host"]
$tnsEntry | Add-Member -type NoteProperty -name Port -value $lineBreakup["Port"]
$tnsEntry | Add-Member -type NoteProperty -name Service -value $(if ($lineBreakup["SERVICE_NAME"] -eq $null) {$lineBreakup["SID"]} else {$lineBreakup["SERVICE_NAME"]})
$tnsentry
if ( $entryName.Length -gt 1)
{
$tnsEntries += $tnsEntry
}
}
}
#$tnsEntries
}
}
end {}
}
I think will need an array to loop around the addresses if the word ADDRESS_LIST is found
PS P:\users\> Get-OraTnsAdminEntries -File "tnsnames.ora"
ENTRY1.world=;DESCRIPTION=;ADDRESS=;PROTOCOL=TCP;HOST=HOST1;PORT=1521;CONNECT_DATA=;SERVER=DEDICATED;SERVICE_NAME=service1;
Name : ENTRY1.world
SimpleName : ENTRY1
Protocol : TCP
Host : HOST1
Port : 1521
Service : service1
ENTRY2.WORLD=;DESCRIPTION=;ADDRESS_LIST=;LOAD_BALANCE=OFF;FAILOVER=ON;ADDRESS=;PROTOCOL=TCP;HOST=HOST3;PORT=1521;ADDRESS=;PROTOCOL=TCP;HOST=HOST4;PORT=1522;CONNECT_DATA=;
SERVICE_NAME=service2;FAILOVER_MODE=;TYPE=SESSION;METHOD=BASIC;RETRIES=2;DELAY=2;
ConvertFrom-StringData : Data item 'ADDRESS' in line 'ADDRESS=' is already defined.
At line:26 char:32
+ ... neBreakup = ConvertFrom-StringData -StringData $line.Replace(";","`n" ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (:) [ConvertFrom-StringData], PSInvalidOperationException
+ FullyQualifiedErrorId : InvalidOperation,Microsoft.PowerShell.Commands.ConvertFromStringDataCommand
;
PS P:\users\>