Reputation: 3521
I have a script that i want to display the connection strings of a database
Import-Module SqlServer
$AS = New-Object Microsoft.AnalysisServices.Server
$AS.connect("server1")
Now if i use the FindByName()
property
$db = $AS.Databases.FindByName("database1")
$db.DataSources[0].ConnectionString
I get back the connection string successfully
however if i use Enumerator
foreach ($db in $AS.Databases.GetEnumerator())
{ $dbName = $db.Name
$dbName
$dbName.DataSources[0].ConnectionString
}
I get back the database name along with error/exception (because it couldnt get connection string for some reason):
database1
Cannot index into a null array.
database2
Cannot index into a null array.
I tried the following also:
$database1 = "database1"
$database1.DataSources[0].ConnectionString
and i also get back the same exception
So why is it that only FindByName works?
for additional info, this is what GetEnumerator lists:
$AS.Databases.GetEnumerator()
but also $AS.Databases
outputs the same thing...so whats even the point of the enumerator?
gm -i $AS.Databases
gm -i $AS.Databases..GetEnumerator()
Upvotes: 2
Views: 131
Reputation: 3521
PowerShell does its own enumerating.
This done the trick!
foreach ($db in $AS.Databases){
Write-Hst $db.Name -Fore green
$db.DataSources | ForEach-Object{$_.ConnectionString}
}
Upvotes: 0
Reputation: 47792
Part of what you're seeing is PowerShell's handling of (some) enumerables. Many (most?) are unrolled by PowerShell automatically, so the call to .GetEnumerator()
isn't needed.
That's what's happening in your last example, looking at $AS.Databases
vs $AS.Databases.GetEnumerator()
. But it's only because you sent it out to the pipeline in that case; it's the display process that did the unrolling (in both cases).
If you did gm -i $AS.Databases
vs gm -i $AS.Databases.GetEnumerator()
you're going to see the difference; same if you assigned each of those to a variable and tried to call methods on them.
But back to using foreach
it should again be redundant: foreach ($db in $AS.Databases)
should work the same as foreach ($db in $AS.Databases.GetEnumerator())
but I don't have this type in my env right now to test that.
So back to the issue at hand inside the foreach
, I suggest you start checking types again. Compare:
$db = $Analysis_Server.Databases.FindByName("database1")
gm -i $db
to
foreach ($db in $AS.Databases.GetEnumerator())
{
gm -i $db
break
}
You might find the types aren't what you think.
This is especially true because you're using dot .
notation, because PowerShell has another array shortcut built-in since version 3, whereby you can use .
on an array of types, to return an array of the .Property
of each item. For example:
$p = Get-Process chrome # choose your own adventure
$p.Count
$p[0].Name
$p.Name
So a property you thought you were accessing on a single object, may have been on an array of objects, and may have been returning an array (or a single object), and handing that in the foreach
may have returned a different quantity, or something, resulting in your attempt to index into what used to be an array, no longer work.
But again it's speculation on my part because I don't have those objects. Hopefully this helps you dig deeper into it though.
Upvotes: 2