2015-07-21 302 views
-3

我有一个SQL脚本来获取数据库大小,我需要在50个SQL服务器上运行它,每个服务器有10个左右的数据库,并为每个数据库获取报告。我如何使用PowerShell来执行该操作。从powershell执行Sql脚本

所以我的问题是如何从poweshell远程执行一个SQL脚本,并让每个数据库

上输出。这是我尝试使用该脚本,我发现它在网上和更新,但它不工作

$dbservers=get-content "c:\powershell\list.txt" 
$Cre = Get-Credential -Credential xxxxxxxxxxxxx 

ForEach-Object ($s in $dbservers) 
{ 
     [System.Reflection.Assembly]::LoadWithPartialName('Microsoft.SqlServer.SMO')  | out-null 
$s = New-Object ('Microsoft.SqlServer.Management.Smo.Server') $server 
$dbs = $s.Databases 
$dbs | SELECT Name -ExpandProperty Name | ForEach-Object{ 
String]$database = $_ 
if (($database -ne "master") -and ($database -ne "tempdb") -and ($database -ne "msdb") -and ($database -ne "model")) { 
$ServerName = $dbservers 
$DatabaseName = $database 
$Query = "Create Table ##temp 
    (
     ServerName nvarchar(250), 
     DatabaseName sysname, 
     Name sysname, 
     physical_name nvarchar(500), 
     size decimal (18,2), 
     FreeSpace decimal (18,2) 
     ) 
     Exec sp_msforeachdb ' 
     Use [?]; 
     Insert Into ##temp (ServerName,DatabaseName, Name, physical_name, Size, FreeSpace) 
     Select @@SERVERNAME ,DB_NAME() AS [DatabaseName], Name, physical_name, 
     Cast(Cast(Round(cast(size as decimal) * 8.0/1024.0,2) as decimal(18,2)) as nvarchar) Size, 

     From sys.database_files ' 

    Select * 
    From ##temp 
    where DatabaseName not in ('master','tempdb','model','msdb') 
    drop table ##temp " 

#Timeout parameters 
$QueryTimeout = 120 
$ConnectionTimeout = 30 

#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 = "Server={0};Database={1};Integrated Security=True;Connect Timeout={2}" -f $ServerName, $DatabaseName,  $ConnectionTimeout 
$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() 
    $ds.Tables 
    } 
    } 
    } 

我收到此错误

The following exception was thrown when trying to enumerate the collection: "Failed to connect to server ..". 
    At C:\Powershell\datafile.ps1:10 char:1 
    + <<<< $dbs | SELECT Name -ExpandProperty Name | ForEach-Object{ 
    + CategoryInfo   : NotSpecified: (:) [], ExtendedTypeSystemException 
    + FullyQualifiedErrorId : ExceptionInGetEnumerator 
+0

谢谢你看我的问题。愿你告诉我什么是得到负面的原因! – sebeid

+0

其实在这种情况下,我不需要在每个数据库上运行它..我想我可以忽略$ Database变量 – sebeid

+0

“不工作”是什么意思?你必须给我们一些工作。 –

回答

0

我平时不运行了这样的任务的查询。 PowerShell可以访问数据库属性。我会给你在特定的服务器上运行的代码,你可以做的是在你的服务器循环内部调用,它会没事的。 如果不行,告诉我,我会发送更多定制的方式来做到这一点。你可以管我的功能不包括系统数据库。 我很懒,现在就去做。

Function Get-FSqlDBFileSizes([string]$serverInstance) 
{ 
    [void][reflection.assembly]::LoadWithPartialName("Microsoft.SqlServer.Smo") 
    try { 


    $results = @() 

    $server = new-object Microsoft.SqlServer.Management.Smo.Server $serverInstance 

    foreach ($db in $server.Databases) 
    { 
     $dbname = $db.Name 
     $fileGroups = $db.FileGroups 
     $intRow=0 
     foreach ($fg in $fileGroups) { 
      If ($fg) { 
       $intRow++ 

       $mdfInfo = $fg.Files | Select Name, FileName, size, UsedSpace 
       $result = New-Object -TypeName PSObject -Property @{ 
        DBName = $dbname 
        Name = $mdfInfo.Name 
        FileName = $mdfInfo.FileName 
        Size = ($mdfInfo.size/1000) 
        UsedSpace = ($mdfInfo.UsedSpace/1000) 
       } 
       $results += $result 

       $logInfo = $db.LogFiles | Select Name, FileName, Size, UsedSpace 
       $result = New-Object -TypeName PSObject -Property @{ 
        DBName = $dbname 
        Name = $logInfo.Name 
        FileName = $logInfo.FileName 
        Size = ($logInfo.size/1000) 
        UsedSpace = ($logInfo.UsedSpace/1000) 
       } 
       $results += $result 
      } 
     } 
    } 

    Write-Output $results 
} 
catch [Exception] { 
    Write-Error $Error[0] 
    $err = $_.Exception 
    while ($err.InnerException) { 
     $err = $err.InnerException 
     Write-Output $err.Message 
    } 
} 
} 

我要去吃午饭什么重玩,我会尽可能地帮你。