この状況を数回受信し、プロセッサが週に30〜50%の負荷でアイドル状態になる可能性があることを見つけた(!)管理者に表示されるまで。 この問題を解決し、スタッフを解放するために、小さなスクリプトが作成されました。非常にシンプルで、多くの類似物があります。何度も何度もその有用性を証明しているので、ここに投稿することにしました。
3台のプリンターが連続して故障し、修理のためにそれらを取り外しました。他の部門のユーザーは、自動クリーニングと印刷サービスの過負荷の結果として、ジョブをキューに送り続けました。私たちは物理的な機器の修理に忙しかった瞬間、仕事から解放されました。
プロセッサから負荷を取り除くには、 C:\ Windows \ System32 \ spool \ PRINTERS \ディレクトリの印刷ジョブをクリアする必要があります。サービスが停止すると、ディレクトリ内のすべてのファイルが削除されます。
Get-Service *spool* | Stop-Service -Force -Verbose Start-Sleep -Seconds 5 $path = "C:\Windows\System32\spool\PRINTERS\" Get-ChildItem $path -File | Remove-Item -Force -Verbose Get-Service Spooler | Start-Service -Verbose
管理通知のために、まず誰が、どの文書を、どのサイズで、どこに印刷するかを保存します。 同時に、オブジェクトを作成する方法の例。
# $temp = Get-Printer | Get-PrintJob # $Jobs = @() # foreach ( $p in $temp ) { # [ordered] # # , # - # html $props = [ordered]@{ ID = $p.Id PrinterName = $p.PrinterName UserName = $p.UserName DocumentName = $p.DocumentName DataType = $p.Datatype SubmittedTime = $p.SubmittedTime Size = $p.Size JobTime = $p.JobTime PagesPrinted = $p.PagesPrinted TotalPages = $p.TotalPages Status = $p.Status } # $props $obj = New-Object -TypeName PSObject -Property $props # $Jobs += $obj } # $Jobs
作業時には、オブジェクトを作成することが望ましいです。
- まず、再利用の方が優れています。
- 新しいプロパティを追加する方が簡単です-$ propsに行を挿入して、すべてのオブジェクトからプロパティを取得するだけです。
- ソート\書き込み\出力\結合\フィルターを使用することをお勧めします。
- 個人的には、複数のオブジェクトのプロパティを1つにまとめて、1つのオブジェクトとしてさらに表示する方が簡単で、作業が簡単です。
例Function Get-NBTName { # NBTSTAT, $data=nbtstat /n | Select-String "<" | where {$_ -notmatch "__MSBROWSE__"} # $lines=$data | foreach { $_.Line.Trim() } # # $lines | foreach { $temp=$_ -split "\s+" [PSCustomObject]@{ Name=$temp[0] NbtCode=$temp[1] Type=$temp[2] Status=$temp[3] } } }
Get-NBTNameを呼び出します| ソートタイプ| Format-Table –オートサイズ
出力は、次のようなオブジェクトのセットになります。
Name NbtCode Type Status ---- ------- ---- ------ MYCOMPANY <1E> GROUP Registered MYCOMPANY <00> GROUP Registered MYCOMPANY <1D> UNIQUE Registered CLIENT2 <00> UNIQUE Registered CLIENT2 <20> UNIQUE Registered
この目的のために、スプーラーのリブート時に診断情報を取得したいので、プロセッサーおよびメモリーによるロードを伴うプロセスのリストを追加します。
# $temp = Get-Process | sort -Property cpu -Descending # $proc = @() foreach ( $p in $temp ) { # $props = [ordered]@{ Name=$p.ProcessName CPU_total_in_seconds=$p.CPU PhysicallMemory_in_Mb=$p.WS/1mb ProcessID=$p.Id } # $obj = New-Object -TypeName PSObject -Property $props # $proc += $obj } $proc
スプーラーに過負荷をかける時期であると判断するために、プロセッサからサンプルが取得され、5秒間しきい値を超えた場合、過負荷になる時期と見なされます。 このスキームは最適ではありません。たとえば、更新プログラムをインストールするとき、このような負荷は保持できますが、運用作業や日常活動では十分であることがわかっているため、そのままにします。
# , 95 $cfi = 0 for( $i=1; $i -le 5; $i++ ) { Start-Sleep -Seconds 1 # $load = Get-WmiObject win32_Processor | select -Property LoadPercentage Write-Host "CPU load $load" -ForegroundColor Green if ($($load.LoadPercentage) -gt 95) { $cfi = $cfi + 1 Write-Host "indicator is $cfi" -ForegroundColor Green } }
5〜10分ごとに実行するには、スクリプトをスケジューラに追加する必要があります。
メールを送信するには、 ここで説明する方法を少し変更して使用します。
メールの送信は別の機能です。なぜなら、 他の場所で使用されている場合、メールサーバーのアドレス「SMTPServer」=「Exchange.domain.ru」をこの場所のサーバーに変更する必要があります。
$params = @{'To'=$MailAddress 'From'='bot@domain.local' 'Subject'="$Subject $Date" 'Body'=$MailBody 'BodyAsHTML'=$True 'SMTPServer'='Exchange.domain.ru' } Send-MailMessage @params -Encoding $encoding
そして、アドレスadmin@domain.ruを管理通知の送信先アドレスに置き換えます。
Send-ToAdmin -MailAddress 'admin@domain.ru' -Style $Style -Subject ' - 100%' -Body $Body -Header1 $header
元のバージョンでは、スクリプトは各プロセスのメモリにロードされたDLLを抽出して、「バグのある」ドライバーをキャッチできました。 この版では 大量の情報を生成し、 ListDllを介して実装されましたが、非常に大きなリストを生成しました。
完全なスクリプトコード:
<# , #> $StyleYellowSimple = @' <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 } table { font-family: "Lucida Sans Unicode", "Lucida Grande", Sans-Serif; font-size: 14px; border-radius: 10px; border-spacing: 0; text-align: center; } th { background: #BCEBDD; color: white; text-shadow: 0 1px 1px #2D2020; padding: 10px 20px; } th, td { border-style: solid; border-width: 0 1px 1px 0; border-color: white; } th:first-child, td:first-child { text-align: left; } th:first-child { border-top-left-radius: 10px; } th:last-child { border-top-right-radius: 10px; border-right: none; } td { padding: 10px 20px; background: #F8E391; } tr:last-child td:first-child { border-radius: 0 0 0 10px; } tr:last-child td:last-child { border-radius: 0 0 10px 0; } tr td:last-child { border-right: none; } </style> '@ <# . #> function Send-ToAdmin { Param ( [string]$MailAddress = 'admin@domain.ru', [string]$Subject = 'Test message', [string]$Header1, [string]$Body, [string]$Style ) BEGIN {} PROCESS { Write-Verbose 'definiting CSS' <# Switch ($Style) { 'YellowSimple' { $head = $StyleYellowSimple; break } 'BlueSimple' { $head = $StyleBlueSimple; break } 'DataTable' {$head = $StyleResposTable; break } default { $head = $StyleYellowSimple; break } }#> $head = $StyleYellowSimple $encoding = [System.Text.Encoding]::UTF8 $Date = Get-Date $MailBody = ConvertTo-HTML -head $head -PostContent $Body -PreContent "<h1>$Subject. Date:$Date</h1><br><h3>$Header1</h3>" | Out-String Write-Verbose "Sending e-mail. Address: $MailAddress" $params = @{'To'=$MailAddress 'From'='bot@domain.local' 'Subject'="$Subject $Date" 'Body'=$MailBody 'BodyAsHTML'=$True 'SMTPServer'='Exchange.domain.ru' } Send-MailMessage @params -Encoding $encoding } END{} } $cfi = 0 for( $i=1; $i -le 5; $i++ ) { Start-Sleep -Seconds 1 $load = Get-WmiObject win32_Processor | select -Property LoadPercentage Write-Host "CPU load $load" -ForegroundColor Green if ($($load.LoadPercentage) -gt 95) { $cfi = $cfi + 1 Write-Host "indicator is $cfi" -ForegroundColor Green } } if ($cfi -gt 2) { # $temp = Get-Process | sort -Property cpu -Descending $proc = @() foreach ( $p in $temp ) { $props = [ordered]@{ Name=$p.ProcessName CPU_total_in_seconds=$p.CPU PhysicallMemory_in_Mb=$p.WS/1mb ProcessID=$p.Id } $obj = New-Object -TypeName PSObject -Property $props $proc += $obj } $temp = Get-Printer | Get-PrintJob $Jobs = @() foreach ( $p in $temp ) { $props = [ordered]@{ ID = $p.Id PrinterName=$p.PrinterName UserName=$p.UserName DocumentName=$p.DocumentName DataType=$p.Datatype SubmittedTime=$p.SubmittedTime Size=$p.Size JobTime=$p.JobTime PagesPrinted=$p.PagesPrinted TotalPages=$p.TotalPages Status=$p.Status } $obj = New-Object -TypeName PSObject -Property $props $Jobs += $obj } # Write-Host " " -ForegroundColor Green Get-Service *spool* | Stop-Service -Force -Verbose Start-Sleep -Seconds 5 $path = "C:\Windows\System32\spool\PRINTERS\" Get-ChildItem $path -File | Remove-Item -Force -Verbose Get-Service Spooler | Start-Service -Verbose $frag1 = $proc | ConvertTo-Html -As table -Fragment -PreContent '<h2> </h2>' | Out-String $frag2 = $Jobs | ConvertTo-Html -As table -Fragment -PreContent '<h2> </h2><br> ( )' | Out-String $Body = '<br><br> .. <br><br>' $Body = $Body + $frag2 + '<br><br>' $Body = $Body + $frag1 + '<br><br>---------------------------------------------------------------------------<br> <br><H2> </H2>' $Date = Get-Date $header = "$Date " $Style = 'YellowSimple' Send-ToAdmin -MailAddress 'admin@domain.ru' -Style $Style -Subject ' - 100%' -Body $Body -Header1 $header }
5〜10分ごとに実行するには、スクリプトをスケジューラに追加する必要があります。
→ 代替スクリプトへのリンク