为什么枚举名称属性不起作用?

时间:2019-02-27 20:00:51

标签: powershell

我有一个脚本,希望显示数据库的连接字符串

Import-Module SqlServer
$AS = New-Object Microsoft.AnalysisServices.Server
$AS.connect("server1")

现在,如果我使用FindByName()属性

$db = $AS.Databases.FindByName("database1")
$db.DataSources[0].ConnectionString

我成功获取了连接字符串

但是如果我使用枚举器

foreach ($db in $AS.Databases.GetEnumerator())
{ $dbName = $db.Name
  $dbName
  $dbName.DataSources[0].ConnectionString
}

我返回数据库名称以及错误/异常(由于某种原因它无法获取连接字符串):

  

数据库1

     

无法索引为空数组。

     

数据库2

     

无法索引为空数组。

我也尝试了以下方法:

$database1 = "database1"
$database1.DataSources[0].ConnectionString

我也得到了同样的例外

那为什么只有FindByName起作用呢?

有关其他信息,这是GetEnumerator列出的内容:

$AS.Databases.GetEnumerator()

enumerator output

而且还有$AS.Databases

输出相同的东西...那么,枚举数的含义又是什么呢?

gm -i $AS.Databases

gmdb

gm -i $AS.Databases..GetEnumerator()

gmenu

2 个答案:

答案 0 :(得分:2)

您看到的一部分是PowerShell对(一些)可枚举的处理。 PowerShell将自动展开许多(大多数?),因此不需要调用.GetEnumerator()

这就是您上一个示例中发生的情况,查看了$AS.Databases$AS.Databases.GetEnumerator()。但这仅仅是因为在这种情况下,您已将其发送到管道中。 (在两种情况下)都是展开的显示过程。

如果您将gm -i $AS.Databasesgm -i $AS.Databases.GetEnumerator()进行比较,将会发现其中的区别;如果您将每个变量分配给一个变量并尝试调用它们上的方法,则同样如此。

但是回到使用foreach还是有必要的:foreach ($db in $AS.Databases) 应该foreach ($db in $AS.Databases.GetEnumerator())相同,但是我没有这种类型env现在进行测试。

因此回到foreach内部的问题,我建议您再次开始检查类型。比较:

$db = $Analysis_Server.Databases.FindByName("database1")
gm -i $db

foreach ($db in $AS.Databases.GetEnumerator())
{ 
    gm -i $db
    break
}

您可能会发现类型与您的想法不符。

尤其如此,因为您使用的是点.,因为PowerShell从版本3开始内置了另一个数组快捷方式,因此您可以在.上使用类型数组,以返回每个项目的.Property的数组。例如:

$p = Get-Process chrome  # choose your own adventure
$p.Count
$p[0].Name
$p.Name

因此,您认为您正在访问单个对象的属性,可能是在对象数组上的属性,可能正在返回数组(或单个对象)的属性,并将其交给foreach返回了不同的数量或其他内容,导致您尝试索引以前是数组的索引不再起作用。

但这又是我的猜测,因为 I 没有这些对象。希望这可以帮助您更深入地研究它。

答案 1 :(得分:0)

PowerShell自己进行枚举。

这成功了!

foreach ($db in $AS.Databases){
  Write-Hst $db.Name -Fore green
  $db.DataSources | ForEach-Object{$_.ConnectionString}
}