我需要制作一个简单的内务脚本来检查 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/