如何在PowerShell中从连接字符串获取数据库名称

4
我正在尝试从PowerShell的连接字符串中获取数据库名称。
"Server=server\instance;uid=User;pwd=Hello;Database=SomeName;"

我可以想到两种方法来做到这一点,一种是搜索字符串Database,直到第一个;之后,在此基础上使用=将字符串分割并选择数据库名称 - 但我不知道如何实现。

第二种方法可以使用DBConnectionStringBuilder,像这样:

$sb = New-Object System.Data.Common.DbConnectionStringBuilder
$sb.set_ConnectionString($cstring)
[string]$Database = ($sb | ? {$_.Keys -eq 'Database'}).value

但是用这种方式,无论我如何尝试过滤数据库名,它都不会返回数据库名。

问题: 如何从连接字符串中获取我的数据库名称?

3个回答

12
使用第二种方法,但简化它:
$cstring = "Server=server\instance;uid=User;pwd=Hello;Database=SomeName;"

$sb = New-Object System.Data.Common.DbConnectionStringBuilder
$sb.set_ConnectionString($cstring)
$Database = $sb.database

这个工作非常完美。

如果你想避免在键不存在的情况下出现错误,有很多方法可以做到这一点。更具惯用性的方法是先查找键:

if ($sb.HasKey('Database')) {
    $Database = $sb.Database
}

或者使用对象自己的TryGetValue方法:
if ($sb.TryGetValue('Database', [ref] $Database)) {
    # It was successful
    # $Database already contains the value, you can use it.
} else {
    # The key didn't exist.
}

字符串解析

在这种情况下我不建议使用这些方法,因为数据库连接字符串格式存在一些灵活性,如果你的代码意识到所有可能情况并试图正确地处理它们,那么为什么要让它去做已经写好的事情(上面的对象)呢?

但是为了完整性,我会使用拆分、正则表达式匹配和捕获来实现:

$cstring -split '\s*;\s*' |
    ForEach-Object -Process {
        if ($_ -imatch '^Database=(?<dbname>.+)$') {
            $Database = $Matches.dbname
        }
    }

所以,我首先在任意数量的空格周围分割了一个分号;。然后,对于每个元素(应该只是键值对),再使用另一个正则表达式进行检查,专门寻找Database=,并捕获紧随其后直到字符串结尾的内容,在一个名为dbname的命名捕获组中。如果匹配成功,则将捕获组的结果赋值给变量。
当存在适当的解析器时,我仍然更喜欢使用它。

1

试一下这个

"Server=server\instance;uid=User;pwd=Hello;Database=SomeName;".split(";") | 
            %{[pscustomobject]@{Property=$_.Split("=")[0];Value=$_.Split("=")[1]}} |
                    where Property -eq "Database" | select Value

0

其他解决方案

$template=@"
{Property*:Abc123}={Value:Test123}
{Property*:Def}={Value:XX}
"@

"Server=server\instance;uid=User;pwd=Hello;Database=SomeName;".replace(";", "`r`n") | ConvertFrom-String -TemplateContent $template |
where Property -eq "Database" | select Value

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接