当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 周五乐趣:创建 PowerShell 跟踪窗口

作者:精品下载站 日期:2024-12-14 07:40:25 浏览:16 分类:玩电脑

周五乐趣:创建 PowerShell 跟踪窗口


[玩转系统] 周五乐趣:创建 PowerShell 跟踪窗口

使用 COM 对象,您可以创建 Internet Explorer 的实例,然后使用 DOM 方法和属性来配置窗口并向其写入文本。这是我以前在 VBScript 中执行的操作的 PowerShell 版本。

#requires -version 2.0

Function Trace-Message {
<#
.Synopsis
Display script trace messages
.Description
This command will launch an instance of Internet Explorer and display user
defined trace messages. The trace message will automatically include a time
stamp. After your script has completed, the window will remain open until you 
manually close it. If you use this command in the PowerShell ISE, you can use 
the -Terminate parameter to close it and clean up the COM object.

The function has parameters to adjust the positioning, size and format of the
Internet Explorer window. You can't change the position or window size once the
window is first created, although you can manually reposition and resize. But
it is possible to specify different values for these settings on a per message
basis:

    Title
    Background Color
    Font
    FontSize

The beginning of every trace window will include information about the user and
computer running the script. This can be useful when troubleshooting a script
that someone else is running.

IMPORTANT: The trace window will only be created if the function detects a
variable in the current scope, usually the script, called TraceEnabled with a
value of $True. This means your script can have trace commands but they won't
do anything unless $TraceEnabled is set to $True.

.Notes
Last Updated: October 30, 2013
Version     : 0.9

.Link
Friday Fun: Create a PowerShell Trace Window
#>

[cmdletbinding(DefaultParameterSetName="Trace")]

Param (
[Parameter(Position=0,Mandatory=$True,HelpMessage="Enter a trace message",
ParameterSetName="Trace")]
[string]$Message,
[Parameter(ParameterSetName="Trace")]
[int]$Top=10,
[Parameter(ParameterSetName="Trace")]
[int]$Left=10,
[Parameter(ParameterSetName="Trace")]
[int]$Width=600,
[Parameter(ParameterSetName="Trace")]
[int]$Height=600,
[Parameter(ParameterSetName="Trace")]
[string]$BGColor="#ffff00",
[Parameter(ParameterSetName="Trace")]
[string]$Title="Trace Messages",
[Parameter(ParameterSetName="Trace")]
[string]$Font="Verdana",
[Parameter(ParameterSetName="Trace")]
[int]$FontSize=2,
[Parameter(ParameterSetName="Kill")]
[alias("kill")]
[switch]$Terminate
)

if ($Terminate) {
  $script:IEWindow.Quit()
  if ($IEWindow) {
    Remove-Variable -name IEWindow -Scope Script
  }
  return
}

#only run if $TraceEnabled is True
if ($script:TraceEnabled) {
#if there isn't an IE window object, create it
If (-NOT $script:IEWindow) {
    $script:IEWindow = New-Object -ComObject "InternetExplorer.Application" 
    $script:IEWindow.navigate("about:blank")
    $script:IEWindow.ToolBar = $False
    $script:IEWindow.AddressBar = $False
    $script:IEWindow.Top = $Top
    $script:IEWindow.Left = $Left
    $script:IEWindow.Width = $Width
    $script:IEWindow.Height = $Height
    $script:IEWindow.Visible = $True
    $script:IEWindow.menubar = $False
    $script:IEWindow.StatusBar = $False   
    $script:IEWindow.Document.IHTMLDocument2_Title = $Title
    $script:IEWindow.document.IHTMLDocument2_bgColor= $BGColor
    #include some default information
    $script:IEWindow.Document.IHTMLDocument2_writeln("<font face=$Font size=$FontSize> $(Get-Date) - User: $($env:USERDOMAIN)$($env:USERName) <br>")
    $elevated = ([security.principal.windowsprincipal]([security.principal.windowsidentity]::Getcurrent())).IsInRole([system.security.principal.securityidentifier]"S-1-5-32-544")
    $script:IEWindow.Document.IHTMLDocument2_writeln("<font face=$Font size=$FontSize> $(Get-Date) - Elevated: $Elevated <br>")
    $script:IEWindow.Document.IHTMLDocument2_writeln("<font face=$Font size=$FontSize> $(Get-Date) - Computer: $env:Computername <br>")
    $os = Get-WmiObject win32_operatingsystem
    $script:IEWindow.Document.IHTMLDocument2_writeln("<font face=$Font size=$FontSize> $(Get-Date) - OS: $($os.caption) <br>")
    $script:IEWindow.Document.IHTMLDocument2_writeln("<font face=$Font size=$FontSize> $(Get-Date) - Ver.: $($os.version) <br>")
    $script:IEWindow.Document.IHTMLDocument2_writeln("<font face=$Font size=$FontSize> $(Get-Date) - Service Pack: $($os.ServicePackMajorVersion).$($os.ServicePackMinorVersion) <br>")
    $script:IEWindow.Document.IHTMLDocument2_writeln("<font face=$Font size=$FontSize> $(Get-Date) - Architecture: $($os.OSArchitecture) <br>")
    $script:IEWindow.Document.IHTMLDocument2_writeln("<font face=$Font size=$FontSize> $(Get-Date) - ******************************<br>")
}

#write the message to the window
$script:IEWindow.Document.IHTMLDocument2_writeln("<font face=$Font size=$FontSize> $(Get-Date) - $Message <br>")
$script:IEWindow.Document.IHTMLDocument2_Title = $Title
$script:IEWindow.document.IHTMLDocument2_bgColor= $BGColor

} #if $TraceEnabled

} #close Trace-Message function

Set-Alias -Name Trace -Value Trace-Message

该函数是在假设您将在脚本中使用它的情况下编写的。我稍后会举一个例子。该函数首先检查可能在脚本范围内的名为 TraceEnabled 的变量。如果设置为 True,该功能将继续。然后它检查是否已经创建了现有的跟踪窗口。如果没有,它会使用一些默认的大小、位置和颜色属性来创建它,所有这些属性都可以通过参数进行更改。创建窗口后,您的消息字符串将写入 Internet Explorer 窗口。我将当前日期和时间添加到消息中。首次创建 IE 窗口时,我还包含了一些默认用户和系统信息。在过去,这通常很有帮助,尤其是在与不太懂技术的用户打交道时。

当您在脚本中包含该函数时,关闭窗口时应该清理所有内容。即使脚本结束后,IE 窗口仍将保留。这很方便,因为您可以从中进行打印、复制和粘贴等。如果您从 PowerShell ISE 运行脚本,事情并不总是能很好地清理,因此我添加了一个 -Terminate 参数(别名为 -Kill)。当您在 ISE 中使用此功能时,运行 Trace -Kill 来关闭窗口并进行清理。

那么你会如何使用这个呢?

好吧,这里有一个脚本版本(我想我之前没有发布过,所以今天你会得到奖励),它获取一些基本的服务器健康信息并创建 HTML 报告。

#requires -version 3.0

<#
ServerHealth.ps1
A script to do a quick health check and create an HTML report.
This version includes my trace function.

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************

#>

[cmdletbinding()]
Param(
[Parameter(Position=0,HelpMessage="Enter the computer name for the report")]
[ValidateNotNullorEmpty()]
[Alias("name","cn")]
[string]$Computername=$env:computername,
[Parameter(Position=1,HelpMessage="Enter the path for the html report")]
[ValidateNotNullorEmpty()]
[string]$Path="ServerHealth.htm",
[Alias("RunAs")]
[System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty,
[switch]$Trace

)
#dot source the Trace function
. C:\scripts\Trace.ps1
if ($trace) {
  $script:TraceEnabled = $True
}

# !!!!!! 
#dot source the Trace function
. C:\scripts\Trace.ps1

if ($trace) {
  #set the variable to turn tracing on
  $script:TraceEnabled = $True
}

#!!!!!!!

#the trace commands will only work if $TraceEnabled = $True
Trace "Starting $($MyInvocation.MyCommand)"

Write-Verbose "Starting $($MyInvocation.MyCommand)"
#initialize an array for HTML fragments
Trace "initializing fragments"
$fragments=@()

$ReportTitle = "Server Health Report: $($Computername.toUpper())"
Trace $ReportTitle
Trace "Defining head"

#this must be left justified        
$head = @"
<Title>$ReportTitle</Title>
<style>
body { background-color:#FFFFFF;
       font-family:Tahoma;
       font-size:12pt; }
td, th { border:1px solid black; 
         border-collapse:collapse; }
th { color:white;
     background-color:black; }
table, tr, td, th { padding: 2px; margin: 0px }
tr:nth-child(odd) {background-color: lightgray}
table { width:95%;margin-left:5px; margin-bottom:20px;}
.alert {background-color: red ! important}
.warn {background-color: yellow ! important}
</style>
<br>
<H1>$ReportTitle</H1>
"@

#build a hashtable of parameters for New-CimSession
$cimParams=@{
ErrorAction="Stop"
ErrorVariable="myErr"
Computername=$Computername
}

Trace "Reporting on computer $Computername"
if ($credential.username) {
    Write-Verbose "Adding a PSCredential for $($Credential.username)"
    Trace "Adding a PSCredential for $($Credential.username)"
    $cimParams.Add("Credential",$Credential)
}

Try {
    #verify if computer is running PowerShell 2 or 3
    Write-Verbose "Test-WSMan $Computername"
    Trace "Test-WSMan $Computername"
    $wsman = Test-WSMan -ComputerName $Computername -ErrorAction Stop -ErrorVariable myErr
    Trace ($wsman | out-string)
}
Catch {
    Write-Warning "Failed to test WSMan for $Computername"
    Write-Warning $myErr.ErrorRecord
    Trace "Oops"
    Trace "Failed to test WSMan for $Computername"
    Trace "Breaking out"
    Break
}

if ([int]($wsman.ProductVersion.Substring(25)) -lt 3) {
#running less than PowerShell 3 so create a DCOM option
 Write-Verbose "$Computername running PowerShell 2.0"
 Trace "$Computername running PowerShell 2.0"
 Trace "Creating new CimSessionOption"
 $cimOption = New-CimSessionOption -Protocol Dcom
 $cimParams.Add("SessionOption",$cimOption)
}

#create a CIM Session
Write-Verbose "Creating a CIM Session"
Trace "Creating a CIM Session"
Try {
    $cs = New-CimSession @cimParams
}
Catch {
    Write-Warning "Failed to create CIM session for $Computername"
    Write-Warning $myErr.ErrorRecord
    Trace "Oops"
    Trace "Failed to create CIM session for $Computername"
    Trace "Breaking"
    Break
}

#get OS data and uptime
Write-Verbose "Getting OS and uptime"
Trace "Getting OS and uptime"
$os = $cs | Get-CimInstance -ClassName Win32_OperatingSystem
$fragments+="<h2>Operating System</h2>"

Trace "Converting OS data to HTML fragment"
$fragments+= $os | select @{Name="Computername";Expression={$_.CSName}},
@{Name="Operating System";Expression={$_.Caption}},
@{Name="Service Pack";Expression={$_.CSDVersion}},LastBootUpTime,
@{Name="Uptime";Expression={(Get-Date) - $_.LastBootUpTime}} |
ConvertTo-HTML -Fragment

Write-Verbose "Getting memory usage"
Trace "Converting memory usage to HTML fragment"
$fragments+="<h2>Memory Usage</h2>"
[xml]$html= $os | 
Select @{Name="TotalMemoryMB";Expression={[int]($_.TotalVisibleMemorySize/1mb)}},
@{Name="FreeMemoryMB";Expression={[math]::Round($_.FreePhysicalMemory/1MB,2)}},
@{Name="PercentFreeMemory";Expression={[math]::Round(($_.FreePhysicalMemory/$_.TotalVisibleMemorySize)*100,2)}},
@{Name="TotalVirtualMemoryMB";Expression={[int]($_.TotalVirtualMemorySize/1mb)}},
@{Name="FreeVirtualMemoryMB";Expression={[math]::Round($_.FreeVirtualMemory/1MB,2)}},
@{Name="PercentFreeVirtualMemory";Expression={[math]::Round(($_.FreeVirtualMemory/$_.TotalVirtualMemorySize)*100,2)}} |
ConvertTo-Html -Fragment

#parse html to add color attributes
Trace "Parsing memory fragment"
for ($i=1;$i -le $html.table.tr.count-1;$i++) {
  $class = $html.CreateAttribute("class")
  #check the value of the percent free memory column and assign a class to the row
  if (($html.table.tr[$i].td[2] -as [double]) -le 10) {                                          
    $class.value = "alert"  
    $html.table.tr[$i].ChildNodes[2].Attributes.Append($class) | Out-Null
  }
  elseif (($html.table.tr[$i].td[2] -as [double]) -le 20) {                                               
    $class.value = "warn"    
    $html.table.tr[$i].ChildNodes[2].Attributes.Append($class) | Out-Null
  }
}
#add the new HTML to the fragment
Trace "adding fragment"
$fragments+= $html.innerXML

#get disk drive status
Write-Verbose "Getting drive status"
Trace "Getting drive status"
$drives = $cs | Get-CimInstance -ClassName Win32_Logicaldisk -filter "DriveType=3"
$fragments+="<h2>Disk Usage</h2>"

Trace "Converting disk usage to HTML fragment"

[xml]$html= $drives | Select DeviceID,
@{Name="SizeGB";Expression={[int]($_.Size/1GB)}},
@{Name="FreeGB";Expression={[math]::Round($_.Freespace/1GB,4)}},
@{Name="PercentFree";Expression={[math]::Round(($_.freespace/$_.size)*100,2)}} |
ConvertTo-Html -Fragment

#parse html to add color attributes
Trace "Parsing memory fragment"
for ($i=1;$i -le $html.table.tr.count-1;$i++) {
  $class = $html.CreateAttribute("class")
  #check the value of the percent free column and assign a class to the row
  if (($html.table.tr[$i].td[3] -as [double]) -le 10) {                                          
    $class.value = "alert"  
    $html.table.tr[$i].ChildNodes[3].Attributes.Append($class) | Out-Null
  }
  elseif (($html.table.tr[$i].td[3] -as [double]) -le 20) {                                               
    $class.value = "warn"    
    $html.table.tr[$i].ChildNodes[3].Attributes.Append($class) | Out-Null
  }
}
Trace "adding disk fragment"
$fragments+=$html.InnerXml
Clear-Variable html

#get recent errors and warning in all logs
Write-Verbose "Getting recent eventlog errors and warnings"
Trace "Getting recent eventlog errors and warnings"
#any errors or audit failures in the last 24 hours will be displayed in red
#warnings in last 24 hours will be displayed in yellow

$Yesterday = (Get-Date).Date.AddDays(-1)
Trace "Yesterday is $yesterday"

$after = [System.Management.ManagementDateTimeConverter]::ToDmtfDateTime($yesterday)
Trace "Converted $yesterday to $after"

#get all event logs with entries
Trace "get all event logs with entries"
$logs = $cs | Get-CimInstance win32_ntEventlogFile -filter "NumberOfRecords > 0"

#exclude security log
$fragments+="<h2>Event Logs</h2>"

#process security event log for Audit Failures
$fragments+="<h3>Security</h3>"

Trace "Getting security event log data and converting to HTML fragment"

[xml]$html = $cs | 
Get-CimInstance Win32_NTLogEvent -filter "Logfile = 'Security' AND Type = 'FailureAudit' AND TimeGenerated >= ""$after""" |
Select -property TimeGenerated,Type,EventCode,SourceName,Message |
ConvertTo-Html -Fragment

Trace "Parsing event log fragment"
if ($html.table) {
   #if a failure in the last day, display in red
    if (($html.table.tr[$i].td[1] -eq 'FailureAudit')  -AND ([datetime]($html.table.tr[$i].td[0]) -gt $yesterday)) {                                          
    $class.value = "alert"  
    $html.table.tr[$i].Attributes.Append($class) | Out-Null
  }
    Trace "Adding event log fragment"
    $fragments+=$html.InnerXml
}
Else {
  #no recent audit failures
  Write-Verbose "No recent audit failures"
  $fragments+="<p style='color:green;'>No recent audit failures</p>"
}

Clear-Variable html
Trace "Getting all other event logs"
foreach ($log in ($logs | where logfilename -ne 'Security')) {
Write-Verbose "Processing event log $($log.LogfileName)"
$fragments+="<h3>$($log.LogfileName)</h3>"

Trace "Converting event log data to HTML fragment"

[xml]$html = $cs | 
Get-CimInstance Win32_NTLogEvent -filter "Logfile = ""$($log.logfilename)"" AND Type <> 'Information' AND TimeGenerated >= ""$after""" |
Select -property TimeGenerated,Type,EventCode,SourceName,Message |
ConvertTo-Html -Fragment

Trace "Parsing fragment"
if ($html.table) {
#color errors in red
for ($i=1;$i -le $html.table.tr.count-1;$i++) {
  $class = $html.CreateAttribute("class")
  #check the value of the entry type column and assign a class to the row if within the last day
  if (($html.table.tr[$i].td[1] -eq 'Error')  -AND ([datetime]($html.table.tr[$i].td[0]) -gt $yesterday)) {                                          
    $class.value = "alert"  
    $html.table.tr[$i].Attributes.Append($class) | Out-Null
  }
  elseif (($html.table.tr[$i].td[1] -eq 'Warning')  -AND ([datetime]($html.table.tr[$i].td[0]) -gt $yesterday)) {                                          
    $class.value = "warn"  
    $html.table.tr[$i].Attributes.Append($class) | Out-Null
  }
} #for

$fragments+=$html.InnerXml
}
else {
  #no errors or warnings
  Write-Verbose "No recent errors or warnings for $($log.logfilename)"
  Trace "No recent errors or warnings for $($log.logfilename)"
  $fragments+="<p style='color:green;'>No recent errors or warnings</p>"
}
Clear-Variable html
} #foreach

#get services that should be running but aren't
Write-Verbose "Getting services that should be running but aren't"
Trace "Getting services that should be running but aren't"
$services = $cs | Get-CimInstance -ClassName win32_service -filter "startmode='Auto' AND state <> 'Running'"
$fragments+="<h2>Services</h2>"

Trace "Converting service data to HTML fragment"
$fragments+= $services | Select Name,Displayname,Description,State | 
ConvertTo-Html -Fragment

$fragments+="<br><i>Created $(Get-Date)</i>"

#create the HTML report
Write-Verbose "Creating an HTML report"
Trace "Creating an HTML report"
Trace "Writing to $path"
ConvertTo-Html -Head $head -Title $reportTitle -body $Fragments | Out-File -FilePath $path -Encoding ascii
Trace (get-item $path | out-string)
Write-Verbose "Saving the HTML report to $Path"
Write-Verbose "Ending $($MyInvocation.MyCommand)"
Trace "Ending $($MyInvocation.MyCommand)"

Write-Host "Report saved to $path" -ForegroundColor Green

当您查看此内容时,您会看到许多跟踪命令。此脚本中的跟踪脚本是点源的,它创建 Trace 的别名。除非 $TraceEnabled 设置为 $True,否则这些命令不会执行任何操作。此版本的脚本包含一个 -Trace 开关,它就是这样做的。从那里开始运行脚本,并将所有跟踪消息写入 IE 窗口。

S:\ServerHealth-Trace.ps1 -Computername CHI-HVR2.GLOBOMANTICS.LOCAL -Credential globomantics\administrator -Trace -Path c:\work\hvr2-health.htm

[玩转系统] 周五乐趣:创建 PowerShell 跟踪窗口

如果出现问题,我可以看到脚本在哪里崩溃或失败。如果一切顺利,我最终会得到这样的报告:

[玩转系统] 周五乐趣:创建 PowerShell 跟踪窗口

服务器运行状况脚本使用 Get-CIMInstance 获取有关最后一天的内存、磁盘使用情况和事件日志的一些信息。如果该脚本检测到远程计算机未运行 PowerShell 3,它将动态创建 DCOM 选项。

您可以将我的 Trace-Message 函数与 Write-Verbose 结合使用。您可以显示相同或不同的信息。它是由你决定。您可以通过 ShowUI 使用 Windows 窗体或 WPF 来实现相同的结果。但每个人都有 Internet Explorer,而且这很容易整合在一起。

顺便说一句,如果您只想获得服务器运行状况脚本的副本而不需要 Trace 命令,请执行以下操作:

#requires -version 3.0

<#
ServerHealth.ps1
A script to do a quick health check and create an HTML report

  ****************************************************************
  * DO NOT USE IN A PRODUCTION ENVIRONMENT UNTIL YOU HAVE TESTED *
  * THOROUGHLY IN A LAB ENVIRONMENT. USE AT YOUR OWN RISK.  IF   *
  * YOU DO NOT UNDERSTAND WHAT THIS SCRIPT DOES OR HOW IT WORKS, *
  * DO NOT USE IT OUTSIDE OF A SECURE, TEST SETTING.             *
  ****************************************************************
#>

[cmdletbinding()]
Param(
[Parameter(Position=0,HelpMessage="Enter the computer name for the report")]
[ValidateNotNullorEmpty()]
[Alias("name","cn")]
[string]$Computername=$env:computername,
[Parameter(Position=1,HelpMessage="Enter the path for the html report")]
[ValidateNotNullorEmpty()]
[string]$Path="ServerHealth.htm",
[Alias("RunAs")]
[System.Management.Automation.Credential()]$Credential = [System.Management.Automation.PSCredential]::Empty
)

Write-Verbose "Starting $($MyInvocation.MyCommand)"
#initialize an array for HTML fragments
$fragments=@()

$ReportTitle = "Server Health Report: $($Computername.toUpper())"

#this must be left justified        
$head = @"
<Title>$ReportTitle</Title>
<style>
body { background-color:#FFFFFF;
       font-family:Tahoma;
       font-size:12pt; }
td, th { border:1px solid black; 
         border-collapse:collapse; }
th { color:white;
     background-color:black; }
table, tr, td, th { padding: 2px; margin: 0px }
tr:nth-child(odd) {background-color: lightgray}
table { width:95%;margin-left:5px; margin-bottom:20px;}
.alert {background-color: red ! important}
.warn {background-color: yellow ! important}
</style>
<br>
<H1>$ReportTitle</H1>
"@

#build a hashtable of parameters for New-CimSession
$cimParams=@{
ErrorAction="Stop"
ErrorVariable="myErr"
Computername=$Computername
}

if ($credential.username) {
    Write-Verbose "Adding a PSCredential for $($Credential.username)"
    $cimParams.Add("Credential",$Credential)
}

Try {
    #verify if computer is running PowerShell 2 or 3
    Write-Verbose "Test-WSMan $Computername"
    $wsman = Test-WSMan -ComputerName $Computername -ErrorAction Stop -ErrorVariable myErr
}
Catch {
    Write-Warning "Failed to test WSMan for $Computername"
    Write-Warning $myErr.ErrorRecord
    Break
}

if ([int]($wsman.ProductVersion.Substring(25)) -lt 3) {
#running less than PowerShell 3 so create a DCOM option
 Write-Verbose "$Computername running PowerShell 2.0"
 $cimOption = New-CimSessionOption -Protocol Dcom
 $cimParams.Add("SessionOption",$cimOption)
}

#create a CIM Session
Write-Verbose "Creating a CIM Session"
Try {
    $cs = New-CimSession @cimParams
}
Catch {
    Write-Warning "Failed to create CIM session for $Computername"
    Write-Warning $myErr.ErrorRecord
    Break
}

#get OS data and uptime
Write-Verbose "Getting OS and uptime"
$os = $cs | Get-CimInstance -ClassName Win32_OperatingSystem 
$fragments+="<h2>Operating System</h2>"
$fragments+= $os | select @{Name="Computername";Expression={$_.CSName}},
@{Name="Operating System";Expression={$_.Caption}},
@{Name="Service Pack";Expression={$_.CSDVersion}},LastBootUpTime,
@{Name="Uptime";Expression={(Get-Date) - $_.LastBootUpTime}} |
ConvertTo-HTML -Fragment

Write-Verbose "Getting memory usage"
$fragments+="<h2>Memory Usage</h2>"
[xml]$html= $os | 
Select @{Name="TotalMemoryMB";Expression={[int]($_.TotalVisibleMemorySize/1mb)}},
@{Name="FreeMemoryMB";Expression={[math]::Round($_.FreePhysicalMemory/1MB,2)}},
@{Name="PercentFreeMemory";Expression={[math]::Round(($_.FreePhysicalMemory/$_.TotalVisibleMemorySize)*100,2)}},
@{Name="TotalVirtualMemoryMB";Expression={[int]($_.TotalVirtualMemorySize/1mb)}},
@{Name="FreeVirtualMemoryMB";Expression={[math]::Round($_.FreeVirtualMemory/1MB,2)}},
@{Name="PercentFreeVirtualMemory";Expression={[math]::Round(($_.FreeVirtualMemory/$_.TotalVirtualMemorySize)*100,2)}} |
ConvertTo-Html -Fragment

#parse html to add color attributes
for ($i=1;$i -le $html.table.tr.count-1;$i++) {
  $class = $html.CreateAttribute("class")
  #check the value of the percent free memory column and assign a class to the row
  if (($html.table.tr[$i].td[2] -as [double]) -le 10) {                                          
    $class.value = "alert"  
    $html.table.tr[$i].ChildNodes[2].Attributes.Append($class) | Out-Null
  }
  elseif (($html.table.tr[$i].td[2] -as [double]) -le 20) {                                               
    $class.value = "warn"    
    $html.table.tr[$i].ChildNodes[2].Attributes.Append($class) | Out-Null
  }
}
#add the new HTML to the fragment
$fragments+= $html.innerXML

#get disk drive status
Write-Verbose "Getting drive status"
$drives = $cs | Get-CimInstance -ClassName Win32_Logicaldisk -filter "DriveType=3"
$fragments+="<h2>Disk Usage</h2>"
[xml]$html= $drives | Select DeviceID,
@{Name="SizeGB";Expression={[int]($_.Size/1GB)}},
@{Name="FreeGB";Expression={[math]::Round($_.Freespace/1GB,4)}},
@{Name="PercentFree";Expression={[math]::Round(($_.freespace/$_.size)*100,2)}} |
ConvertTo-Html -Fragment

#parse html to add color attributes
for ($i=1;$i -le $html.table.tr.count-1;$i++) {
  $class = $html.CreateAttribute("class")
  #check the value of the percent free column and assign a class to the row
  if (($html.table.tr[$i].td[3] -as [double]) -le 10) {                                          
    $class.value = "alert"  
    $html.table.tr[$i].ChildNodes[3].Attributes.Append($class) | Out-Null
  }
  elseif (($html.table.tr[$i].td[3] -as [double]) -le 20) {                                               
    $class.value = "warn"    
    $html.table.tr[$i].ChildNodes[3].Attributes.Append($class) | Out-Null
  }
}

$fragments+=$html.InnerXml
Clear-Variable html

#get recent errors and warning in all logs
Write-Verbose "Getting recent eventlog errors and warnings"

#any errors or audit failures in the last 24 hours will be displayed in red
#warnings in last 24 hours will be displayed in yellow

$Yesterday = (Get-Date).Date.AddDays(-1)
$after = [System.Management.ManagementDateTimeConverter]::ToDmtfDateTime($yesterday)

#get all event logs with entries
$logs = $cs | Get-CimInstance win32_ntEventlogFile -filter "NumberOfRecords > 0"
#exclude security log
$fragments+="<h2>Event Logs</h2>"

#process security event log for Audit Failures
$fragments+="<h3>Security</h3>"

[xml]$html = $cs | 
Get-CimInstance Win32_NTLogEvent -filter "Logfile = 'Security' AND Type = 'FailureAudit' AND TimeGenerated >= ""$after""" |
Select -property TimeGenerated,Type,EventCode,SourceName,Message |
ConvertTo-Html -Fragment

if ($html.table) {
   #if a failure in the last day, display in red
    if (($html.table.tr[$i].td[1] -eq 'FailureAudit')  -AND ([datetime]($html.table.tr[$i].td[0]) -gt $yesterday)) {                                          
    $class.value = "alert"  
    $html.table.tr[$i].Attributes.Append($class) | Out-Null
  }
    
    $fragments+=$html.InnerXml
}
Else {
  #no recent audit failures
  Write-Verbose "No recent audit failures"
  $fragments+="<p style='color:green;'>No recent audit failures</p>"
}

Clear-Variable html

#process all the other logs
foreach ($log in ($logs | where logfilename -ne 'Security')) {
Write-Verbose "Processing event log $($log.LogfileName)"
$fragments+="<h3>$($log.LogfileName)</h3>"

[xml]$html = $cs | 
Get-CimInstance Win32_NTLogEvent -filter "Logfile = ""$($log.logfilename)"" AND Type <> 'Information' AND TimeGenerated >= ""$after""" |
Select -property TimeGenerated,Type,EventCode,SourceName,Message |
ConvertTo-Html -Fragment

if ($html.table) {
#color errors in red
for ($i=1;$i -le $html.table.tr.count-1;$i++) {
  $class = $html.CreateAttribute("class")
  #check the value of the entry type column and assign a class to the row if within the last day
  if (($html.table.tr[$i].td[1] -eq 'Error')  -AND ([datetime]($html.table.tr[$i].td[0]) -gt $yesterday)) {                                          
    $class.value = "alert"  
    $html.table.tr[$i].Attributes.Append($class) | Out-Null
  }
  elseif (($html.table.tr[$i].td[1] -eq 'Warning')  -AND ([datetime]($html.table.tr[$i].td[0]) -gt $yesterday)) {                                          
    $class.value = "warn"  
    $html.table.tr[$i].Attributes.Append($class) | Out-Null
  }
} #for

$fragments+=$html.InnerXml
}
else {
  #no errors or warnings
  Write-Verbose "No recent errors or warnings for $($log.logfilename)"
  $fragments+="<p style='color:green;'>No recent errors or warnings</p>"
}
Clear-Variable html
} #foreach

#get services that should be running but aren't
Write-Verbose "Getting services that should be running but aren't"
$services = $cs | Get-CimInstance -ClassName win32_service -filter "startmode='Auto' AND state <> 'Running'"
$fragments+="<h2>Services</h2>"
$fragments+= $services | Select Name,Displayname,Description,State | 
ConvertTo-Html -Fragment

$fragments+="<br><i>Created $(Get-Date)</i>"

#create the HTML report
Write-Verbose "Creating an HTML report"

ConvertTo-Html -Head $head -Title $reportTitle -body $Fragments | Out-File -FilePath $path -Encoding ascii

Write-Verbose "Saving the HTML report to $Path"
Write-Verbose "Ending $($MyInvocation.MyCommand)"

Write-Host "Report saved to $path" -ForegroundColor Green

今天您将获得双倍的乐趣。您对这一切有何看法?一如既往,我期待听到您的想法。

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯