标签: powershell

SQL Server SMO 方法“Discover()”

我想我刚刚找到了 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"),因为这是您可以调用该方法的唯一方法。尽管如此,仍在寻找一种方法来提取对象名称、类型和所有者。

sql-server powershell smo

6
推荐指数
1
解决办法
961
查看次数

对具有提升权限的集群执行 Powershell SMO 以更新服务帐户

我正在使用 Powershell 脚本来更新故障转移集群中命名 SQL 实例上的服务帐户。我正在尝试使用 SMO 和 WMI 来更新它,以便我可以更新主动节点上的服务帐户并将其填充到其他被动节点(如果我在配置工具中手动更新会发生这种情况)。我正在尝试在本地机器上执行脚本但更新远程服务器。根据我的 Google 搜索,我看到的错误似乎与安全相关,如果我在远程计算机上以提升的权限(以管理员身份)本地运行脚本,则该错误会成功。

编码:

[reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.SqlWmiManagement") | Out-Null
$mc=New-Object -TypeName Microsoft.SqlServer.Management.Smo.Wmi.ManagedComputer "SQLHOST01"

$srvcs= $mc.Services | Where {$_.name -like "*INSTANCE01*"} | Where {$_.Type -like "Sql*"}

$srvcs | ft name,servicestate,serviceaccount

foreach ($s in $srvcs){
    $s.SetServiceAccount("FOO\Bar","strongpass")
}
Run Code Online (Sandbox Code Playgroud)

错误:

Exception calling "SetServiceAccount" with "2" argument(s): "Set service account failed. "
At line:11 char:5
+     $s.SetServiceAccount("FOO\Bar","strongpass")
+     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : FailedOperationException
Run Code Online (Sandbox Code Playgroud)

使用:Windows 2008 R2(远程)SQL 2008 R2(远程)Windows 7 with SQL 2012 …

sql-server-2008 sql-server clustering powershell

6
推荐指数
1
解决办法
1591
查看次数

从 SQL 代理执行远程 Powershell 脚本

测试SQL服务器作业在执行Powershell脚本时挂起。它确实使用我的登录名和Powershell窗口工作,但不使用Agent帐户和工作。该SQL Agent用户具有读/写/执行权限与PowerShell脚本的目录。

例子:

Run as: SQL Server Agent Service Account

powershell.exe -file \\Server02\test2\Test.ps1
Run Code Online (Sandbox Code Playgroud)

代理帐户也已获得访问权限。

这个测试文件目前做了一些非常基本的事情:显示一个字符串。

当它运行时,它不会显示错误消息,因为它只是不响应。您知道发生了什么,或者缺少哪些安全设置吗?

sql-server powershell sql-server-agent

6
推荐指数
1
解决办法
1万
查看次数

将当前服务器名称从 SQL Server 代理作业传递到 PowerShell

我有一个 SQL Server 代理作业,它在一个步骤中调用 PowerShell 脚本。我想将 SQL 服务器名称和当前作业 ID 传递给我的脚本。

有了工作 ID,我没有问题。但是使用服务器名称...

我的 PowerShell 调用如下所示:

.\StopServices.ps1 -ServerName $(ESCAPE_DQUOTE(A-SVR)) -JobId $(ESCAPE_DQUOTE(JOBID))
Run Code Online (Sandbox Code Playgroud)

作业 ID 工作正常,但服务器名称为空。

如何将服务器名称传递给我的 PowerShell 脚本?

powershell sql-server-agent

6
推荐指数
1
解决办法
1437
查看次数

在不同的服务器上运行 PowerShell 脚本 - 从 SQL Server 作业内部

我有一个备份 SSAS 数据库程序

这是一种魅力。

现在我的服务器被 SSAS 备份填满,我想删除超过 2 天的备份文件。

为了实现这一点,我使用了以下 POWERSHELL 脚本:

#-------------------------------------------------------------------------------
# Script to delete old SSAS backup files
#
# Marcelo Miorelli
# 
# 19-novembre-2014 Wed
#-------------------------------------------------------------------------------


#-- connect to the remote server -- SQLBILON1
#
ENTER-PSSESSION sqlbilon1


#-- set the Path where the backup files (.abf) are located
#
$path = 'H:\SQLBackups'

#-- set the number of days backups should be deleted -- in this case 2
#
$NumberOfDays = 2

#-- …
Run Code Online (Sandbox Code Playgroud)

sql-server ssas powershell linked-server maintenance-plans

5
推荐指数
1
解决办法
4082
查看次数

Powershell 缺少 FCI 的集群名称

我正在运行以下简单的 Powershell 命令。

$Server = New-Object ('Microsoft.SqlServer.Management.Smo.Server') 'SerName'
$Server | SELECT *
Run Code Online (Sandbox Code Playgroud)

对于 FCI 集群,该ClusterName值始终为空,并且ClusterQuorumStateClusterQuorumType始终为NotApplicableIsClustered虽然设置为 True。

如果我针对可用性组运行它,我会返回集群名称和其他两个属性的正确值。

Powershell 中有没有办法获取 FCI 实例的集群名称?我可以使用另一个 cmdlet?

sql-server clustering powershell

5
推荐指数
1
解决办法
302
查看次数

在标记化作业步骤中处理“找不到变量”

我有一个代理作业,通常由 WMI 事件触发。该作业中有一个令牌,它会自动从 WMI 事件中获取一个值并将其替换为该步骤的 Powershell 代码,例如:

$alert_wmi_state = '$(ESCAPE_SQUOTE(WMI(State)))';
Run Code Online (Sandbox Code Playgroud)

SQL 代理配置为选中所有作业响应警报设置的替换令牌,因此,当 WMI 事件触发时,替换会正常发生,并且运行的代码为:

$alert_wmi_state = '7';
Run Code Online (Sandbox Code Playgroud)

但是,该作业有可能手动运行(即右键单击,在步骤中启动作业...),并且我希望我的步骤代码能够优雅地处理此问题,因此我在步骤中进一步采用了以下逻辑:

if ($alert_wmi_state -eq ('$' + '(ESCAPE_SQUOTE(WMI(State)))')) {
    ...
}
Run Code Online (Sandbox Code Playgroud)

...理论是,$从 中分离(ESCAPE_SQUOTE...将合理地意味着这不被识别为令牌,因此不会被替换,因此测试将按字面意思读取:

if ($alert_wmi_state -eq '$(ESCAPE_SQUOTE(WMI(State)))') {
    ...
}
Run Code Online (Sandbox Code Playgroud)

但是,手动运行作业时,在运行我的任何代码之前,SQL 代理总是会在该步骤中出错(无论它是配置为CmdExec作业步骤类型还是PowerShell作业步骤类型),并显示错误Variable WMI(State) not found

我的猜测是,这是因为替换ESCAPE_SQUOTE发生步骤代码实际解析/加载之前,因此代理永远不会运行该步骤。

我希望我可以有两个步骤,一个带有令牌,一个没有,并且让标记化步骤的失败操作启动非标记化步骤,但是步骤代码的重复是不可取的。

所以,我的问题是,有什么方法可以优雅地处理步骤代码中不存在步骤令牌的情况吗?

sql-server powershell sql-server-agent

5
推荐指数
1
解决办法
890
查看次数

与 xp_cmdshell 一起使用时调用 SQLCMD 不起作用

我正在尝试从一堆服务器获取磁盘空间报告并将它们插入到 sql 表中..

下面是我正在尝试做的示例,服务器名称将从表中填充并作为逗号分隔列表传递。即使传递一台服务器也有相同的结果

set @ps = 'powershell.exe -noexit -c "

$computers=Get-WmiObject -Class Win32_Volume '+@servernames+'
foreach($computer in $computers) 
{ 
$pscomputername=$computer.pscomputername 
$name=$computer.name 
$capacity=$computer.capacity 
$freespace=$computer.freespace 
$Label=$computer.Label 

$insertquery=" 
INSERT INTO [dbo].[temp_disksdata] 
           (
           [servername] ,
           [DiskName] ,
           [Capacity(GB)] ,
           [FreeSpace(GB)],
           [label]
           )
     VALUES 
           (''$pscomputername'' ,
           ''$name'' ,
           ''$capacity'',
           ''$freespace'',
           ''$Label''
           ) 
GO
" 

Invoke-SQLcmd  -query $insertquery -ServerInstance ''someserver'' -Database dbname

}

"';
Run Code Online (Sandbox Code Playgroud)

现在我尝试将变量传递给 xp_cmdshell,如下所示

execute xp_cmdshell @ps;
Run Code Online (Sandbox Code Playgroud)

当在 SSMS 中调用时,上面返回 null,但在 powershell 中工作..

任何想法为什么?

以下是我尝试过的一些事情

1. shell 和 ssms 都使用相同的帐户(admin) 2.
尝试了多种方法,例如导入模块
3.XP_CMDshell 有效,但这仅针对此查询返回 …

sql-server powershell sql-server-2012 xp-cmdshell

5
推荐指数
1
解决办法
1887
查看次数

从 Powershell 连接到 DAC 时,错误日志中出现“最大数量‘1’专用管理员连接已存在”消息

我正在通过 PowerShell 的专用管理员连接 (DAC) 连接到 SQL Server(2016 和 2017 最新版本)。

SQL Server 错误日志中记录以下错误消息:

日期 2019 年 4 月 2 日下午 1:59:13 记录 SQL Server(当前 - 2019 年 4 月 2 日下午 1:59:00)

源登录

消息
无法连接,因为已存在最大数量“1”的专用管理员连接。在建立新连接之前,必须通过注销或结束进程来删除现有的专用管理员连接。[客户端:127.0.0.1]

查询成功运行。已经尝试了许多连接字符串管理迭代;这是迄今为止最强大的。

Stack Exchange 上有一个解决方案,该解决方案涉及在关闭连接之前终止 spid,但这也会向 SQL Server 错误日志中抛出一条令人讨厌的消息,因此没有什么乐趣。

检查sys.dm_exec_sessions没有发现任何有趣的事情;使用此技术,没有连接保持打开状态。下面的 PowerShell 有一个虚拟查询,我无法谈论为什么我们要以这种方式连接,因为它是专有的,但它是 100% 必要的,它是一个非常快速的连接,我需要每 10 次执行一次分钟。

这个错误只是噪音。DAC 查询按预期运行和工作。

即使在静止的系统上重新启动,每次都会记录该错误。没有其他 DAC 连接正在使用 - 如果有,Powershell 会在命令提示符处抛出明显的错误消息。

有趣的是,当使用 时sqlcmd,SQL Server 错误日志中不会记录任何错误消息。

#begin powershell script
$SqlServerName = "server\instance"

$DbQuery = "
INSERT INTO  master.dbo.sometable(value1,value2) …
Run Code Online (Sandbox Code Playgroud)

sql-server powershell sql-server-2016 sql-server-2017 dac

5
推荐指数
1
解决办法
2592
查看次数

使用 Invoke-Sqlcmd 时如何本机返回输出?

如何本地记录来自 PowerShell Invoke-Sqlcmd 的输出?

我正在使用 Invoke-Sqlcmd 循环遍历一个大的(50,000-90,000 个 SQL 文件,每个文件中有 1-10 个插入)小 SQL 插入语句集。大多数插入语句运行正确,但一些字符串太长,我收到“字符串或二进制数据将被截断”错误。

现在我正在使用 Start-Transcript 来捕获输出并识别有问题的插入语句,但 Start-Transcript 捕获了所有内容。我只想捕获错误 - 或者 - 只捕获 Invoke_Sqlcmd 语句输出。

如果这行得通(我认为应该如此),我就准备好了:

Invoke-Sqlcmd -InputFile $sql -ServerInstance LocalHost -Database Test_DB -Credential $pwd -Verbose -OutputSqlErrors $true | Out-File -FilePath "C:\Temp\Errorlog.txt" -Append
Run Code Online (Sandbox Code Playgroud)

或者,如果这有效:

Invoke-Sqlcmd -InputFile $sql -ServerInstance LocalHost -Database Test_DB -Credential $pwd -Verbose -OutputSqlErrors $true | Tee-Object -FilePath "C:\Temp\Errorlog.txt" -Append
Run Code Online (Sandbox Code Playgroud)

但这些都不起作用。

我也尝试过这种怪物,但我根本没有从中得到任何错误:

$sqls = (Get-ChildItem -Path "I:\2019_06_24\_SQL"-Filter *.sql | Sort-Object -Property CreationTime).FullName
        foreach ($sql in $sqls)
            {
            $Error.Clear()
            try …
Run Code Online (Sandbox Code Playgroud)

powershell sqlcmd

5
推荐指数
1
解决办法
2753
查看次数