我的任务是发现在我们的域中运行的所有 SQL Server 实例。在某些情况下,每个服务器有多个实例。我见过两种不同的 PowerShell 方法来查找这些实例,但似乎都没有找到所有实例。
1) 使用 WMI
$srvr = New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer $computerName
$instances = $srvr | ForEach-Object {$_.ServerInstances} | Select @{Name="fullName";Expression={$computerName +"\"+ $_.Name}}
return $instances
Run Code Online (Sandbox Code Playgroud)
2)使用远程注册表(与 Get-SQLInstance 1 一样)
我遇到的最大问题是,并非我所知道的所有服务器都使用 SQL Server WMI 提供程序运行,也不是所有服务器都允许远程注册。有没有第三种方法?我可以使用远程桌面访问所有服务器,但我正在查看大约 30 台机器,并希望尽可能避免手动步骤。这仅需要适用于 SQL Server 2008 及更高版本,虽然了解其他 SQL Server 服务 (SSIS/SSAS/SSRS) 会很好,但我主要关注 SQL Server 本身。
我想我刚刚找到了 SQL Server SMO 和 PowerShell 最酷的东西。我被要求编写一个脚本来查找 SQL Server 实例中每个对象的所有者。我在 Technet/MSDN SQL Server 库上找到了一个脚本,但认为使用 PowerShell 获取它会容易得多,并且能够一次访问网络上的所有实例。
在玩的过程中,我在 Database 类中遇到了这个方法:Discover()
因此,如果您使用此代码:
#Load SMO
[System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.Smo') | Out-Null
$srv = New-Object 'Microsoft.SqlServer.Management.Smo.Server' "your instance name"
$db = $srv.Databases
$db.Discover()
Run Code Online (Sandbox Code Playgroud)
当你运行最后一行时,如果你连接到一个有很多数据库的实例,你会看到你的控制台开始滚动文本,就像它在药物上一样。
好吧,我去做了 $db | gm
,它几乎向您展示了 SMO 对象中可用的每个 TypeName。
现在我的问题。我可以执行$db.Discover() | Select Name, Owner
,它将开始吐出带有名称和所有者值的所有内容。
我怎样才能获得返回对象的对象类型(比如它是触发器、模式、表等)?到目前为止,我似乎无法弄清楚。
编辑
到目前为止,我发现它似乎只能在数据库级别“发现”事物。显然,我在控制台缓存中的某个地方设置 $db
了类似$db = ($srv.Databases).Item("aDatabase")
,因为这是您可以调用该方法的唯一方法。尽管如此,仍在寻找一种方法来提取对象名称、类型和所有者。
我的任务是评估允许第三方供应商在 SSMS 中远程调试其查询所涉及的安全风险。这意味着用户的帐户必须是 sysadmin 固定角色。虽然这意味着用户出于所有意图和目的“拥有”SQL Server 实例,但我们已将该实例设置为特定于该供应商的服务帐户。我只剩下主要评估使用 xp_cmdshell 可以造成的损害。
我知道系统管理员几乎可以撤消为监视该活动而实施的任何内容,但是如果有办法监视它(也许使用扩展事件?)和/或使用日志功能,它将为我们提供额外的安全级别。