sql - Powershell foreach SQL Server查询随机整理DataSet

标签 sql powershell dataset powershell-5.0

我需要制作一个简单的内务脚本来检查 14 个 SQL Server 的表。 我最终使用了Adam's来自this的脚本问题。

但是,在运行时,它会跳过发布随机数量的服务器的结果,然后将其查询转储到一个表中,然后单独执行任何剩余的服务器。我做错了什么? (因为我无法评论 Adam 的回答)

我不介意整理表中的所有数据并在最后转储,但如果更容易完成的话,然后使用服务器名称和结果列。

这是我的脚本,下面是示例输出;

$year = Get-Date -Format yyyy
$servers = gc 'ServerList.txt'

foreach ($server in $servers) 
{
    try
    {
        $ServerName = "$server"
        $DatabaseName = "DatabaseName"
        $Query = "select count(*) from Alarm_Activations where Activation_Date not like '%$year%'"
        #$ds = $null -Tried adding this to fix the issue

        #Timeout parameters
        $QueryTimeout = 120
        $ConnectionTimeout = 30

        Write-Host ""
        Write-Host ""
        Write-Host "  Checking $server "

        #Action of connecting to the Database and executing the query and returning results if there were any.
        $conn = New-Object System.Data.SqlClient.SQLConnection
        $ConnectionString = "Data Source=$server\sqlexpress;Initial Catalog=DatabaseName;Connect Timeout=30; Integrated security=true;"
        $conn.ConnectionString = $ConnectionString

        $conn.Open()

        $cmd = New-Object system.Data.SqlClient.SqlCommand($Query,$conn)
        $cmd.CommandTimeout = $QueryTimeout

        $ds = New-Object system.Data.DataSet
        $da = New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
        [void]$da.fill($ds)
        $conn.Close()

        Write-Host "Number of activations older than $year :"
        $ds.Tables
    } 
    catch 
    {
        Write-Error "Something went wrong. Seems you have to do it manually!"
        return
    }
}

输出示例

转储表的点似乎是随机的,但通常超过一半的服务器。

我最早看到的是Server-5,最新的;服务器14;

& CheckAlarmActivation.ps1


  Checking Server-1
Number of activations older than 2019 :



  Checking Server-2
Number of activations older than 2019 :


  Checking Server-3
Number of activations older than 2019 :


  Checking Server-4
Number of activations older than 2019 :


  Checking Server-5
Number of activations older than 2019 :


  Checking Server-6
Number of activations older than 2019 :


  Checking Server-7
Number of activations older than 2019 :


  Checking Server-8
Number of activations older than 2019 :


  Checking Server-9
Number of activations older than 2019 :


  Checking Server-10
Number of activations older than 2019 :
Column1
-------
      0
      0
      0
   3318
   1069
   4375
      8
   9357
     74
   1735


  Checking Server-11
Number of activations older than 2019 :
   7917


  Checking Server-12
Number of activations older than 2019 :
   3583


  Checking Server-13
Number of activations older than 2019 :
   5622


  Checking Server-14
Number of activations older than 2019 :
   4166

最佳答案

就像 AdminOfThings 评论的那样,使用 Write-Output 而不是 Write-Host。因为您使用的是 Write-Host 流并且只是输出一个变量(该变量转到输出流)($ds.Tables),所以您在同时控制台。

除了使用Write-Output之外,我还通过将数据库调用的结果(以及您想要从它们返回的任何结果)存储为放入集合中的 PSObject 来解决该问题,然后在迭代所有服务器后,您可以一次性格式化输出(到控制台、生成 csv/html 报告等)。这种方法的好处是,如果其中一台服务器宕机,您的脚本也不会失败。

编辑 我更新了 catch block 以正确地捕获异常。我还更新了从数据集中获取值的位置以进行扩展,这样您就没有数据行对象。如果您有多个列,或者您想要根据某些列创建计算属性,则可以使用更高级的Select-Object 逻辑。 SO post with more info 。就您而言,您只想获取记录数。

$serverResults = @()
$servers = "srv1","srv2"

foreach ($server in $servers) 
{
  # Create an instance of a custom object that will hold the results of your query. Add properties as needed, they can be other complex objects, or simple types. 
   $serverResultInstance = New-Object PSObject -Property @{
   ServerName = $server
   DatabaseName = $DatabaseName 
   Tables = $null
   Exception = $null
   }
 try{
    #Connect to DB like you do (Don't use Write-Host)
    #Add your dataset for this instance 
    $ServerName = "$server"
        $DatabaseName = "dbName"
        $Query = "select count(*) from sys.columns"
        #$ds = $null -Tried adding this to fix the issue

        #Timeout parameters
        $QueryTimeout = 120
        $ConnectionTimeout = 30

        Write-Host ""
        Write-Host ""
        Write-Host "Checking $server"

        #Action of connecting to the Database and executing the query and returning results if there were any.
        $conn = New-Object System.Data.SqlClient.SQLConnection
        $ConnectionString = "Data Source=$server;Initial Catalog=$DatabaseName;Connect Timeout=$ConnectionTimeout; Integrated security=true;"
        $conn.ConnectionString = $ConnectionString

        $conn.Open()

        $cmd = New-Object system.Data.SqlClient.SqlCommand($Query,$conn)
        $cmd.CommandTimeout = $QueryTimeout

        $ds = New-Object system.Data.DataSet
        $da = New-Object system.Data.SqlClient.SqlDataAdapter($cmd)
        [void]$da.fill($ds)

        # Instead of keeping the whole table/row object, expand out the column you want. If you have multiple columns or tables in your dataset you would need to change these values. 
    $serverResultInstance.Tables = $ds.Tables[0] | select -ExpandProperty Column1
 }
 catch{
    #This should have been $_.Exception
    $serverResultInstance.Exception = $_.Exception
 }
 finally{
    $conn.Close()
    $serverResults  += $serverResultInstance
 }
}
foreach($result in $serverResultInstance){
# Format your output here. Make a csv, send an email, etc. Or just:
 Write-Output "Number of activations older than $year :"
 Write-Output $result.Tables

}

关于sql - Powershell foreach SQL Server查询随机整理DataSet,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58858811/

相关文章:

c# - 重构 Linq 查询

php - 如何从一个输入 Html 表单插入数组字符串并从中获取另一数据

mysql - FROM 子句中的表是否必须在 WHERE 子句中?

powershell - 以分钟和秒为单位测量执行时间

c# - 避免 XML 文档中的冗余

java - VoltDB - 小数值有太多零

azure - 使用 PowerShell 在 Azure 应用程序中创建多个委派权限?

Powershell 工作流程 - Get-Service 不过滤

c# - 在 C# 中合并两个 XML 文件,其中一个不一致

python - 跨 Django 数据库移动大型数据集