【问题标题】:Output Error (Duplicates) Powershell输出错误(重复) Powershell
【发布时间】:2015-09-13 11:31:44
【问题描述】:

据我了解,我的查询结果未正确保存/转发。应该发生的是,对于每台服务器(svr01、svr03、svr05、svr06、svr08),我应该获取他们的操作系统、完整域名等。然后这些信息用于填充我的 SQL 数据库(Hal0Test)。但是,该信息永远不会被发送,我不知道如何解决这个问题。

我在我的 powershell 脚本中添加了一个小的 html 输出,以便在本地查看我的结果。 html 对我来说更容易打开,然后运行 ​​SQL Server Management Studio 并刷新该程序。但我仍然希望将所有这些变量发送到数据库。

目标:更正重复问题开始将该信息发送到我的 sql 数据库。如果你能帮助我,那就太棒了!

代码:

Write-Output " `n Start of Hal0 `n";

#Start of Server Connection
$connectionString = "Server=QAUTILITYDB01;Database=Hal0Test;Integrated Security=True;"
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$command = $connection.CreateCommand()

$ServerArray = [System.Collections.ArrayList]@()
$query = "SELECT ServerName FROM ServerList"
$command.CommandText = $query
$ServerNames = $command.ExecuteReader()

$table = new-object “System.Data.DataTable”
$table.Load($ServerNames)

$ServerArray = $table | select -Expand ServerName

#Variables for each Server in Array
$ServerArray | ForEach-Object {
    # $ServerArray returns each server name

    #Operating System
    $os    = Get-WmiObject -Class Win32_OperatingSystem -Computer $_ 
    #Server's Memory (RAM) Usage Average
    $memAvg    = gwmi -Class win32_operatingsystem -computername $_ | 
    Select-Object @{Name = "MemoryUsage"; Expression = {“{0:N2}” -f ((($_.TotalVisibleMemorySize - $_.FreePhysicalMemory)*100)/ $_.TotalVisibleMemorySize) }} 
    #Server's CPU (Proccess) Usage Average
    $cpuAVG = Get-WmiObject -computername $_ win32_processor |  
    Measure-Object -property LoadPercentage -Average | Select Average 
    #Server's Hard Drives (MB) Free/Used
    $disks = Get-WmiObject -Class Win32_LogicalDisk -Computer $_ |
             Where-Object {$_.DriveType -eq 3} |
             ForEach-Object {
                 '{0} {1:D} MB Free/{2:D} MB Used' -f $_.DeviceID,
                     [int]($_.FreeSpace/1MB), [int]($_.Size/1MB)
             }

    New-Object -Type PSCustomObject -Property @{
      'FQDN' = $_
      'ServerName' = $os.PSComputerName
      'OperatingSystem' = $os.Caption
      'CPUAvg' = "$($cpuAVG.Average)%"
      'MemAvg' = "$($memAvg.MemoryUsage)%"
      'Disks'  = $disks -join ' | '
    }

    $command.CommandText = "UPDATE ServerList SET FQDN = '$_', OS = '$($os.Caption)' WHERE ServerName = '$($os.PSComputerName)';"
    $result = $command.ExecuteNonQuery()

 Write-Output " `n Start of Hal0 `n";

#Start of Server Connection
$connectionString = "Server=QAUTILITYDB01;Database=Hal0Test;Integrated Security=True;"
$connection = New-Object System.Data.SqlClient.SqlConnection
$connection.ConnectionString = $connectionString
$connection.Open()
$command = $connection.CreateCommand()

$ServerArray = [System.Collections.ArrayList]@()
$query = "SELECT ServerName FROM ServerList"
$command.CommandText = $query
$ServerNames = $command.ExecuteReader()

$table = new-object “System.Data.DataTable”
$table.Load($ServerNames)

$ServerArray = $table | select -Expand ServerName


#Start of HTML Code
$Outputreport = 
                "<HTML><TITLE> IDI Server Report </TITLE>
                <BODY background-color:peachpuff> 
                <font color =""#99000"" face=""Microsoft Tai le""> 
                <H2> IDI Server Report </H2></font> 
                <Table border=1 cellpadding=0 cellspacing=0> 
                <TR bgcolor=gray align=center> 
                    <TD><B>Server Name</B></TD> 
                    <TD><B>FQDN</B></TD>
                    <TD><B>CPU Usage</B></TD> 
                    <TD><B>RAM Usage</B></TD> 
                    <TD><B>Disk Space</B></TD> 
                    <TD><B>Operating System</B></TD>
                <TD><B>Query result</B></TD></TR>" 
$ServerArray | ForEach-Object {
    # $ServerArray returns each server name
    # collection code skipped
    $command.CommandText = "UPDATE ServerList SET FQDN = '$_', OS = '$($os.Caption)' WHERE ServerName LIKE '$($os.PSComputerName)%';"
    $result = $command.ExecuteNonQuery()
    if($cpuAVG.Average -ge "2")  
      {  
        $Outputreport += "<TR bgcolor=#FF0000>"  
      }  
    else 
      { 
        $Outputreport += "<TR bgcolor=#E6E6FA>"  
      } 
    $Outputreport +=
        "<TD>$($os.PSComputerName)</TD>
        <TD align=center>$($_)</TD>
        <TD align=center>$("$($cpuAVG.Average)%")</TD>
        <TD align=center>$("$($memAvg.MemoryUsage)%")</TD>
        <TD align=center>$($disks)</TD>
        <TD align=center>$($os.Caption)</TD></TR>
        <TD align=center>$($result)</TD></TR>"

}
    $Outputreport += "</Table></BODY></HTML>"  
    $Outputreport | out-file C:\Users\king\Desktop\HalO\ServerReport.html
    Invoke-Expression C:\Users\king\Desktop\HalO\ServerReport.html
    }

Write-Output "`n End of Hal0";
#End

HTML 结果:

SQL 数据库:仅供参考,我在“char”中手动添加

【问题讨论】:

  • 这里有很多信息,我不确定哪些部分实际上是相关的。问题仅与您的 SQL 查询有关吗?您在尝试插入表格时是否看到错误?
  • 对此很抱歉,但我的问题是我的程序,正如您在图像中看到的那样,正在复制而不是从 5 台服务器中的每台服务器中获取信息。但我不知道为什么,因为在控制台中它正在从每个服务器中提取正确的信息。但似乎我的 ServerArray 没有正确存储结果。

标签: html sql-server database sql-server-2008 powershell


【解决方案1】:

您正在最外层的 foreach 循环中完整创建基于 HTML 的报告,但您的 $_ 仅限于当前正在处理的服务器。相反,在主循环开始之前将包装器 HTML 放入 $Outputreport,然后在循环中添加带有当前数据的 &lt;tr&gt;...&lt;/tr&gt; 部分。并将第二个循环放在$ServerArray 上。在您的报告中还包括$result,显然所有更新查询都会导致0 row(s) updated,您不明白为什么。 (一个疯狂的猜测:编码不匹配(UTF16 与数据库的 UTF8))您可能会决定 INSERT INTO ServerList 数据并删除旧行,这样您的关键字段肯定会保持一致。

#Start of HTML Code
$Outputreport = "<HTML><TITLE> IDI Server Report </TITLE>
                <BODY background-color:peachpuff> 
                 <font color =""#99000"" face=""Microsoft Tai le""> 
                 <H2> IDI Server Report </H2></font> 
                 <Table border=1 cellpadding=0 cellspacing=0> 
                 <TR bgcolor=gray align=center> 
                   <TD><B>Server Name</B></TD> 
                   <TD><B>FQDN</B></TD>
                   <TD><B>CPU Usage</B></TD> 
                   <TD><B>RAM Usage</B></TD> 
                   <TD><B>Disk Space</B></TD> 
                   <TD><B>Operating System</B></TD>
                   <TD><B>Query result</B></TD></TR>" 
$ServerArray | ForEach-Object {
    # $ServerArray returns each server name
    # collection code skipped
    $command.CommandText = "UPDATE ServerList SET FQDN = '$_', OS = '$($os.Caption)' WHERE ServerName LIKE '$($os.PSComputerName)%';"
    $result = $command.ExecuteNonQuery()
    if($cpuAVG.Average -ge "2")  
      {  
        $Outputreport += "<TR bgcolor=#FF0000>"  
      }  
    else 
      { 
        $Outputreport += "<TR bgcolor=#E6E6FA>"  
      } 
    $Outputreport += @"
        <TD>$($os.PSComputerName)</TD>
        <TD align=center>$($_)</TD>
        <TD align=center>$($cpuAVG.Average)%</TD>
        <TD align=center>$($memAvg.MemoryUsage)%</TD>
        <TD align=center>$($disks)</TD>
        <TD align=center>$($os.Caption)</TD></TR>
        <TD align=center>$($result)</TD></TR>
        "@
    # used a here-string for clarification  
} 
$Outputreport += "</Table></BODY></HTML>"  

我还将 where 子句更改为 like 语句,可能您的数据库在 ServerName 列中有 FQDN。

【讨论】:

  • 非常感谢!!!使用您的代码,我能够推送到服务器,但遗憾的是它仅适用于服务器列表中的最后一行。我做错了什么。我编辑了我的问题以反映新的代码和错误。
  • 你为什么放弃收藏代码?我已将答案中的代码缩短为评论,因为不需要修补该段,现在您的问题中有code skipped :)
  • 在从数据库接收到Write-Host $ServerArray 后立即执行。根据 HTML 报告,您的服务器阵列只有服务器 08 重复了 5 次。另外,我已将您的收藏代码重新编辑为您的问题。
  • 效果很好。我会在服务器端检查并报告
猜你喜欢
  • 2014-09-15
  • 2014-08-26
  • 1970-01-01
  • 2015-02-13
  • 2020-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多